I've been away from python for quite some time but enjoyed using django on a project 5-6 years ago. I thought it was really full-featured and fairly intuitive, but it seemed to rely heavily on what seems to be considered an older paradim of submitting forms, and getting sent to a new page, etc, vs the "Single Page Application" concept.
I know it was possible to do SPAs with django-rest or something, but I'm curious if Django has mostly stayed in this "older" paradigm or if its more .. modernized at this point?
Django is ver good if you are writing non SPA with a SQL backend. If you are writing a SPA without a SQL backend (any of the noSQL DBs), it becomes much easier to just use flask/quartz/fastAPI, as you don't benefit from the Django niceties.
and when you find yourself actually needing "niceties" they are right there waiting...
I've been trying those alternative libraries from time to time and there is always the thought "I wish I started this in Django" when project becomes more complex than a basic endpoint.
DRF works really well.
You'll inevitably have some other pages that require non SPA, for example your login pages, signup and things like that. So regular Django forms come in handy there.
Does SPA concept work well with search engines? I moved away from web development, but SPAs used to be very bad if you wanted to appear in Google search.
Btw I was looking into Django recently, they are still using the “older” paradigm you are referring to.
I think Google is capable of handling SPAs these days (it can execute js now), so works fine mostly (might still be better to serve full HTMLs to start with).
It technically can render javascript, but there's a performance penalty that negatively affects your crawl budget.
If you're twitter or facebook, or have enough domain reputation already that your crawl budget is big enough to offset, then it doesn't matter. If you are not already a big deal, then it takes a lot of off-site traction to overcome.
Practically speaking, for two otherwise-even sites just starting out, a statically rendered site has a pretty significant SEO advantage over a JS-only site.
The old paradigm is new again. Combining Django with HTMX, you get the simplicity of rendering HTML on the server side and not deal with bloated and over-engineered Javascript frameworks. Flask/Django with HTMX and Tailwindcss is a fantastic combination and my current preferred stack. I also add Alpinejs to this mix for interactivity. Really enjoying the heightened productivity that this setup provides.
I tried out htmx + django a little but got stuck doing something more than trivial. Do you have an example of a starter project that has intermediate concepts demonstrated? Maybe this can help me get over the hump.
Honestly, the SPA concept is flawed, and throws away all the good things that HTML gave you out of the box. I'm glad people are starting to come to their senses and are moving away from it.
You only have to build the application once, for one thing. With SPAs you have to build the application on the backend and then build it again on the front end.
For fancier, SPA style applications we utilize Strawberry to add GraphQL support into Django. It's pretty enjoyable to work with, but I would love for GraphQL to get more love from Django officially.
Subscriptions are still a bit thorny, but have come a long way now that ASGI and channels are a focus for the Django team.
That and HTMX + Alpine.js are a strong combination.
(I also had a bash at building a similar tool for Django called Tetra but unfortunately haven't had the time needed to commit to it: https://www.tetraframework.com)
I'm relieved to see that the idea that SPAs are a "modern", better way of doing things seems to finally be fading a little bit.
My experience from lessons learned over the past ten years is that SPAs generally take longer to build, are usually slower to load, have much worse accessibility and are more expensive to debug and maintain.
For a great deal of web projects you're better off with the "old paradigm".
That said... I do think there's an argument to be made that Django should include core framework features that make working with SPAs easier, rather than farming that out entirely to Django REST Framework.
Django 4.2 does have one nod in that direction: https://docs.djangoproject.com/en/4.2/releases/4.2/#django-c... - "ManifestStaticFilesStorage now has experimental support for replacing paths to JavaScript modules in import and export statements with their hashed counterparts".
Why not just absorb DRF? Which as I understand is the leading choice for many, so I wonder if some effort should be dedicated to reducing fragmentation.
The problem with having things like DRF inside of Django core is that it reduces their speed of iteration.
Django releases a new version every six months. Packages that aren't part of Django core are free to release on a different schedule, which really helps when you're trying to innovate on something new.
In DRF's case it's now mature and stable enough that maybe that wouldn't be so much of a problem... but it's still not clear to me that having it in Django core would be a net benefit (aside from as a marketing thing) than having it live independently as it does today.
The problem with DRF being an external package is that it does thing slightly different than Django itself would do it.
DRF’s validators don’t implement `__eq__`, Serializers doesn’t implement `serializer._meta.fields` on the base class (you have to instantiate the serializer to access anything other than `declared_fields`), lack of async view support, and on and on.
I find DRF grating and would pay anything to have an official Django REST api contrib package.
1/ "older" paradigm is still extremely useful in many cases
2/ we also use Django as a backend for SPAs. Here with Vuetify
3/ using the HTMX paradigm, you're both doing SPA and "older paradim of submitting forms"
Surely a better metric would be actual jobs as advertised on Indeed.com where there's a metric ton of React jobs which doesn't look like changing anytime soon regardless of what may be happening on Twitter.
Yea, React is moving to the server. Check out Remix, which pushes the more "old school" approach of doing forms. I think Next is coming soon with something for that.
I feel like lately js (and more importantly typescript) frameworks have been more popular. If someone were to start a new project today, how does Django standup to the current offerings?
I agree, although I really wish Django and sqlAlchemy would have evolved similar methods/APIs. My struggle is flipping between projects that use one or the other and tripping over the syntax.
Django's hidden powers are its highly customisable admin UI and ORM. Add to it Django REST framework and you have a solid backend for a wide category of web apps, from the old pre-XMLHttpRequest apps to SPAs. Flask or FastAPI get you going fast, but you quickly realise that you have to write a lot of the code that comes with Django for free.
Honestly, I think the generic and model views are way more impressive than the ORM or the admin. They take away all of the boilerplate usually associated with CRUD apps.
I've used them for quite a while but came back to the old function views. The Generic Views are a mess to understand, the hierarchy tree gets so complicated. See for example : https://ccbv.co.uk/projects/Django/4.1/django.views.generic.... there are 9 classes in the inheritance tree. For every slight change from the default behavior you need to research the documentation, find which method to override…
In the end I have to write a bit more of boilerplate each time (and with tools like copilot it's a non-issue) but it's 10x faster to understand what a view does and how when reading code.
> For every slight change from the default behavior you need to research the documentation, find which method to override…
I just use an IDE which allows me to Ctrl+Click into any symbol and see its implementation and underlying classes (and do so recursively if needed). That saves me from having to lookup the documentation all the time.
I just got into Django after working with Node/Java for years. It's honestly depressing once I realized I have spent so much time building CRUD stuff that would have taken 10x less time with Django.
I feel the opposite. Django is fine, but python ecosystem is the big problem. The lack of true multi threading means for even the simplest of apps you quickly need to have multiple deployments, celery workers etc to handle different kinds of workloads.
It is different. JS is popular because people who write SPAs also want to write backends in the same language.
What I really like about Django and Python ecosystem in general is the kind of stability that it doesn't move too fast and break things, which happens in JS land too often. And Python is a nicer language of the two, for me at least.
But at the end of the day, you can combine both. I work for Baserow now and we combine Nuxt + Django. You can also simplify it to Vue/React + Vite + serve it with Django, use cookies-base auth etc.
Personally I feel like I've unlocked a superpower with this one trick (using rails, but this applies equally to django and similar "old" page-load-based frameworks)
1. build your app in the normal, old way. just doing SSR for showing and editing boring content is so much faster than building it in react.
2. I have a tiny scrap of JS that digs through elements on the page, and if they have a class, creates a React root there and passes in some params. I then wrapped generating those replace-me-with-a-react-root elements in a Rails helper function.
(2 is my "fine I'll do it myself" after Rails 7's new js stuff broke react-rails for me.)
This might be colored by me being a backend dev and data engineer type of person and I have terrifically little patience for writing javascript. But pages where I've followed this "SSR + some React doodads for when you really need special sauce" pattern end up so much easier and faster to write than cramming it all into a huge SPA.
I'm sure if you're building something deeply fancy then doing it all in React makes sense, but I find there's really only a couple pages that actually do end up being 100% react and the rest end up fine just having a text field here or there or a little widget thingy being the React components and the rest just being SSR.
I'm sure this doesn't scale if you're google or something either but even on my most complicated pages this still loads visibly faster than many other sites I use.
I don't do proper web dev work and tried Django ages ago. So, this is a very narrow opinion. I use mainly flask and firebase these days as a indiehacker.
I don't think currenlty there are any solid alternatives beyond Nestjs+Typescript, ruby on rails and laravel. The sentimemt of their community is that these frameworks are built for web development in mind.
While I think for Python based web framework like Django the sentiment is that you are using Python already and here is a web framework written in Python. If you look at some of the Rust based web frameworks you will understand what I am saying. The merit of the framework is the language it was written in. This makes hiring web developers difficult as most candidates will be Python Developer who knows Django and not web developers who knows Python. There are very few people who learned Python to use Django. But everyone learned javascript to use nodejs, or ruby to use ruby on rails.
If I am writing enterprise level where Python is used I will pick one of those 3 frameworks and use a Python based API framework like DRF or FastAPI for building internal APIs.
Python is literally the easiest language to learn. Any web dev can pick it up, and Django is much more productive than NestJS. Rails and Laravel are nice options too. No Rust or Java options come close.
The admin page, DB integration, robust feature set, and insanely good documentation make Django a slam dunk for me. I do understand your sentiment though and for any website that requires a lot of interactivity you need a JS oriented framework like NextJS.
If I need a database and interactivity I pair NextJS with Django Restapi.
We use django for our websites where I work, and I use it for personal projects for the ORM.
How do you like the ORM for FastAPI? I've wanted to try it but since I already know how to use django it's been hard to find a reason to try FastAPI. Currently I _really_ like Django's orm.
You end up missing Django's ORM when you can't use it, as well. I've tried my best to recreate the experience with Prisma in JS but it took me awhile to get to a place where I felt like I wasn't duplicating schema...
FastAPI doesn’t come with an ORM out of the box. There’s https://sqlmodel.tiangolo.com/ which wraps SQLAlchemy and allows defining the database models with pydantic-like classes.
For me neither Django nor SQLAlcjemy hit the right spot when trying to define “pure” domain models that have no dependency (I.e. no ORM information). For that I created a repository pattern approach that converts “domain mode operations” into SQLModel query operations via filter specifications (https://martinfowler.com/apsupp/spec.pdf).
The result is that I always need to define 2 models: one is my pure domain model and another is a “table model” (defined in SQLAlchemy) along with a mapping between the two (for cases where there’s no 1-to-1 trivial mapping between their fields). Also making some of the SQLAlchemy magic (for example back propagating relational attributes) is messy.
But if you want to produce some quick applications I think SQLModel+FastAPI works quite well. I don’t think is as mature as Django though.
There is no official ORM for FastAPI. You have to pick one yourself. Probably the most common choice is Sqlalchemy, which is not nearly as nice to work with as Django's ORM, in my opinion. It's also annoying to wire up.
For non-db backed projects (but let's be honest, how many projects don't use a DB) FastAPI is a great choice.
One of the apps I worked on ended up switching away from Django because of all the magic in the ORM slowing things down significantly for us. Same DB and API, just written in FastAPI was a 4x speedup. That was 2+ years ago though, so cannot say where things currently are. And now anything new I do is FastAPI, and only deal with Django for existing apps. Yes there are annoyances with not having that ORM, but worth it for what I have been working on at least.
For new projects async runtimes are enticing but its really hard to switch to or from a async runtime with an existing project. Similarly moving to or from the Django ORM or SQLAlchemy + Pydantic is too much work for most to justify.
So whatever fully featured framework you start with will be the one you stick with. They all have warts and hurdles but should get you where you need to be from a business perspective.
How does FastAPI compare on the ORM and serialization front? I enjoy using djangorestframework and it’s been nice leverage for me, especially dealing with binary formats (eg keys).
A good compromise I have found is to use Django Ninja [1]. It is inspired by FastAPI, so it has a lot of the nice things like the automatically generated Swagger/OpenAPI docs, as well as having routers as decorators, and using python types for automatic serialization.
While I think FastAPI is great in its first class async support, Django has the Django ORM, plus Django Admin, which for me have been indisposable.
Is FastAPI still a bus factor of one? Last time I looked a year or two ago, there were quite a few “easy” unresolved PRs that could have been handled with a bigger team.
Django may be considered boring and old school, but it does so many things right that the barrier to switching is quite high.
In what scenarios it would be beneficial to rewrite the Django app in Go? Do you mean something specific when saying that Go would be good replacement?. I/O heavy or computation heavy service?
I actually did to rewrite parts of django's auth, caching in go in order to be compatible with a grpc-based mobile app. The django source code is well documented and easy enough to understand, so it wasn't a probablem signing sessions, creating users etc in go and then using them in django.
For django itself, once I slapped a database caching layer on top and tuned gunicorn/uvicorn, there were no performance issues. Go is faster, but django is fast enough.
I keep wanting to switch personal projects to use my professional language C#, but there still is nothing as reasonable as a django default admin view with CRUD for the entities you create, so I always go back.
Django is cool. But miss the type safety. FastAPI is better but is openapi spec second. Not easy for clients.
However now doing mostly Kotlin with Ktor and loving it. Just a better language which makes it much easier to trust the compiler. Lot less unit testing needed.
86 comments
[ 2.9 ms ] story [ 160 ms ] threadI know it was possible to do SPAs with django-rest or something, but I'm curious if Django has mostly stayed in this "older" paradigm or if its more .. modernized at this point?
I've been trying those alternative libraries from time to time and there is always the thought "I wish I started this in Django" when project becomes more complex than a basic endpoint.
Btw I was looking into Django recently, they are still using the “older” paradigm you are referring to.
If you're twitter or facebook, or have enough domain reputation already that your crawl budget is big enough to offset, then it doesn't matter. If you are not already a big deal, then it takes a lot of off-site traction to overcome.
Practically speaking, for two otherwise-even sites just starting out, a statically rendered site has a pretty significant SEO advantage over a JS-only site.
Then the SEO penalty is just the increased page size (maybe some extra loading time). But at least the content can be crawled normally.
Just don't try to pretend it's a "good for everything" tool.
(I know this is not HTML per se, but it's by far my biggest pet peeve with SPA since forever, so I had to mention it.)
Subscriptions are still a bit thorny, but have come a long way now that ASGI and channels are a focus for the Django team.
https://www.django-unicorn.com/
That and HTMX + Alpine.js are a strong combination.
(I also had a bash at building a similar tool for Django called Tetra but unfortunately haven't had the time needed to commit to it: https://www.tetraframework.com)
My experience from lessons learned over the past ten years is that SPAs generally take longer to build, are usually slower to load, have much worse accessibility and are more expensive to debug and maintain.
For a great deal of web projects you're better off with the "old paradigm".
That said... I do think there's an argument to be made that Django should include core framework features that make working with SPAs easier, rather than farming that out entirely to Django REST Framework.
Django 4.2 does have one nod in that direction: https://docs.djangoproject.com/en/4.2/releases/4.2/#django-c... - "ManifestStaticFilesStorage now has experimental support for replacing paths to JavaScript modules in import and export statements with their hashed counterparts".
Django releases a new version every six months. Packages that aren't part of Django core are free to release on a different schedule, which really helps when you're trying to innovate on something new.
In DRF's case it's now mature and stable enough that maybe that wouldn't be so much of a problem... but it's still not clear to me that having it in Django core would be a net benefit (aside from as a marketing thing) than having it live independently as it does today.
DRF’s validators don’t implement `__eq__`, Serializers doesn’t implement `serializer._meta.fields` on the base class (you have to instantiate the serializer to access anything other than `declared_fields`), lack of async view support, and on and on.
I find DRF grating and would pay anything to have an official Django REST api contrib package.
Edit: grammar
I’d pick it for these reasons.
In the end I have to write a bit more of boilerplate each time (and with tools like copilot it's a non-issue) but it's 10x faster to understand what a view does and how when reading code.
I just use an IDE which allows me to Ctrl+Click into any symbol and see its implementation and underlying classes (and do so recursively if needed). That saves me from having to lookup the documentation all the time.
I haven't built SPAs yet, but I'm looking into trying Unicorn: https://www.django-unicorn.com/
Overall, I've found it great for prototyping up something really quickly. I think this is where the "batteries-included" helps a lot
What I really like about Django and Python ecosystem in general is the kind of stability that it doesn't move too fast and break things, which happens in JS land too often. And Python is a nicer language of the two, for me at least.
But at the end of the day, you can combine both. I work for Baserow now and we combine Nuxt + Django. You can also simplify it to Vue/React + Vite + serve it with Django, use cookies-base auth etc.
1. build your app in the normal, old way. just doing SSR for showing and editing boring content is so much faster than building it in react.
2. I have a tiny scrap of JS that digs through elements on the page, and if they have a class, creates a React root there and passes in some params. I then wrapped generating those replace-me-with-a-react-root elements in a Rails helper function.
(2 is my "fine I'll do it myself" after Rails 7's new js stuff broke react-rails for me.)
This might be colored by me being a backend dev and data engineer type of person and I have terrifically little patience for writing javascript. But pages where I've followed this "SSR + some React doodads for when you really need special sauce" pattern end up so much easier and faster to write than cramming it all into a huge SPA.
I'm sure if you're building something deeply fancy then doing it all in React makes sense, but I find there's really only a couple pages that actually do end up being 100% react and the rest end up fine just having a text field here or there or a little widget thingy being the React components and the rest just being SSR.
I'm sure this doesn't scale if you're google or something either but even on my most complicated pages this still loads visibly faster than many other sites I use.
I don't think currenlty there are any solid alternatives beyond Nestjs+Typescript, ruby on rails and laravel. The sentimemt of their community is that these frameworks are built for web development in mind. While I think for Python based web framework like Django the sentiment is that you are using Python already and here is a web framework written in Python. If you look at some of the Rust based web frameworks you will understand what I am saying. The merit of the framework is the language it was written in. This makes hiring web developers difficult as most candidates will be Python Developer who knows Django and not web developers who knows Python. There are very few people who learned Python to use Django. But everyone learned javascript to use nodejs, or ruby to use ruby on rails.
If I am writing enterprise level where Python is used I will pick one of those 3 frameworks and use a Python based API framework like DRF or FastAPI for building internal APIs.
If I need a database and interactivity I pair NextJS with Django Restapi.
Wut? It's more a case of "everyone learned javascript to do button rollovers in the browser, and then nodejs allowed them to do more".
How do you like the ORM for FastAPI? I've wanted to try it but since I already know how to use django it's been hard to find a reason to try FastAPI. Currently I _really_ like Django's orm.
For me neither Django nor SQLAlcjemy hit the right spot when trying to define “pure” domain models that have no dependency (I.e. no ORM information). For that I created a repository pattern approach that converts “domain mode operations” into SQLModel query operations via filter specifications (https://martinfowler.com/apsupp/spec.pdf).
The result is that I always need to define 2 models: one is my pure domain model and another is a “table model” (defined in SQLAlchemy) along with a mapping between the two (for cases where there’s no 1-to-1 trivial mapping between their fields). Also making some of the SQLAlchemy magic (for example back propagating relational attributes) is messy.
But if you want to produce some quick applications I think SQLModel+FastAPI works quite well. I don’t think is as mature as Django though.
For non-db backed projects (but let's be honest, how many projects don't use a DB) FastAPI is a great choice.
For new projects async runtimes are enticing but its really hard to switch to or from a async runtime with an existing project. Similarly moving to or from the Django ORM or SQLAlchemy + Pydantic is too much work for most to justify.
So whatever fully featured framework you start with will be the one you stick with. They all have warts and hurdles but should get you where you need to be from a business perspective.
While I think FastAPI is great in its first class async support, Django has the Django ORM, plus Django Admin, which for me have been indisposable.
[1] - https://django-ninja.rest-framework.com/
Django may be considered boring and old school, but it does so many things right that the barrier to switching is quite high.
If service needs extra performance then can be rewritten in Golang later.
For django itself, once I slapped a database caching layer on top and tuned gunicorn/uvicorn, there were no performance issues. Go is faster, but django is fast enough.
Like, keep the Node.js code but use Django admin.
Are there any comparable projects to Djano admin? A database model that generates an optionally customizable admin UI?
However now doing mostly Kotlin with Ktor and loving it. Just a better language which makes it much easier to trust the compiler. Lot less unit testing needed.
And Kotlin feels really pythonic