Django: what’s new in 6.0

2 months ago (adamj.eu)

I love how Django just keeps slowly improving at every release. 6.0 is especially cool, including lots of really useful new features. Who said dependable tech was dull - this is the way is should be done. Well done all who contribute.

  • Same! I've been using it since pre-1.0 and love it. I am currently a few blocks away from it's birthplace.

    Probably the wrong time or place but I am also on the market literally as of yesterday so if anyone is looking for an experienced Django guy, I'm your man! oldspiceap@gmail.com

Any code or blog written by Adam is worth spending some time on.

It will be interesting to see how the tasks framework develops and expands. I am sad to see the great Django-Q2 lumped in with the awful Celery though.

  • Celery is the worst background task framework, except for all the others.

    There are bugs and issues, but because so many people are using it, you’re rarely the first to stumble upon a problem. We processed double-digit millions of messages daily with Celery + RabbitMQ without major obstacles. Regardless of what people say, it should be your first go-to.

    • Celery has way too much magic crammed into it, it is very annoying to debug, and produces interesting bugs. Celery is/was also a "pickle-first" API and this almost always turns out to be the wrong choice. As a rule of thumb, persisting pickles is a really bad idea. Trying to hide IPC / make-believe that it's not there tends to be a bad idea. Trying to hide interfaces between components tends to be a bad idea. Celery combines all of these bad ideas into one blob. The last time I looked the code was also a huge mess, even for old-guard-pythonic-code standards.

    • I think Celery has a lot of magic happening under it. When the abstractions are so high, it's important they never leak and you don't see anything below the turtles you are supposed to see.

      I often prefer designing around explicit queues and building workers/dispatchers. One queuing system I miss is the old Google App Engine one - you set up the queue, the URL it calls with the payload (in your own app), the rate it should use, and that's it.

  • I tried django-q and I thought it was pretty terrible. The worst was that I couldn't get it to stop retrying stuff that was broken. Sometimes you ship code that does something unexpected, and being able to stop something fast is critical imo.

    Fundamentally I think the entire idea behind celery and django-q is mostly misguided. People normally actually need a good scheduler and a bring-your-own queue in tables that you poll. I wrote Urd to cover my use cases and it's been rock solid.

  • I've been using Celery for years. What is the major issues you have with it and how does Django Q2 help?

    I also use Kafka on other tech stacks but that's another level completely and use case.

  • Why is celery awful?

  • I’m currently stuck with the tech debt of Celery myself. I understand that! Does Django Tasks support async functions?

  • I'm of the opinion that django task apps should only support a single backend. For example, django-rq for redis only. There's too many differences in backends to make a good app that can handle multiple. That said, I've only used celery in production before, and I'm willing to change my mind.

I've been using Django on and off at work for the past few years. I really like it. That being said, I still find its ORM difficult. I understand it now that since it's an opinionated framework, I need to follow Django way of thinking. The main issue is that at work, I have multiple databases from different business units. So I constantly have to figure out a way to deal with multiple databases and their idiosyncrasies. I ended up doing a lot of hand holding by turning off managed, inspectdb and then manually delete tables I don't want to show via website or other reasons. For green webapps we have, django is as good as it gets.

  • Agreed, and their DB migration workflow leaves much to be desired. By not storing a schema/DB state alongside code, Django depends on the current DB state to try and figure it out from scratch every time you run a DB command. Not to mention defining DB state from model code is inherently flawed, since models are abstractions on top of database tables. I much prefer the Rails way of composing migrations as specific DB instructions, and then getting models 'for free' on top of those tables.

  • Do you use Django's multiple databases support ? (https://docs.djangoproject.com/en/6.0/topics/db/multi-db/)

    • Yes, we have to in order to use a lot of the features. The core issue for us is really the way Django assumes code represents database state. In normal webapp where the application has full control of the database, that's a good idea. But our databases are overloaded for simple transactions, analytics, users managements, jobs and AI. Business uses the databases in various ways such as Power BI, Aquastudio, etc.. Django app is actually a tiny part of the database. As you can imagine, we duck tape the heck out of the databases, and Django goes bonkers when things aren't matching.

  • Also don't underestimate setting up e.g. views or materialized views even that you can use through the ORM to query. It helps a lot and allows you to combine fine tuning SQL with ease of use through Django, and get a lot of performance out of it. Just remember to create them in the migration scripts.

  • I've been using Django for the last 10+ years, its ORM is good-ish. At some point there was a trend to use sqlalchemy instead but it was not worth the effort. The Manager interface is also quite confusing at first. What I find really great is the migration tool.

    • Since Django has gained mature native migrations there is a lot less point to using SQLAlchemy in a Django project, though SQLAlchemy is undeniably the superior and far more capable ORM. That should be unsurprising though - sqlalchemy is more code than the entire django package, and sqlalchemy + alembic is roughly five times as many LOC as django.db, and both are similar "density" code.

      1 reply →

Template partials look good, which is one of the key reasons frameworks like React are as good and popular as they are, because you can reuse small segments of code.

I’m very much an Odoo guy who has dabbled with Django (and notably, celery in the past) but as someone who makes huge use of the Odoo OCA queue module[0], I never understood why Django never made use of the Postgres LISTEN/NOTIFY to offload tasks. Maybe this is my misunderstanding as I’m pretty green with the Django ecosystem as a whole.

[0] https://github.com/oca/queue

Template Partials and HTMX seems like the Django equivalent of View Components and Stimulus for Rails, which is nice.

Also, good to see first class support for Tasks, among a lot of other niceties!

I have been using Django on and off for the last 5-6 years, and it does have the advantage of having batteries loaded but it just feel heavy overall

I find templates atrocious to use for component fragments like this, that's why I wrote a Python component library when I started using Django with HTMX. Order of magnitude more pleasant to use, works with _every_ Python web framework not just Django: https://compone.kissgyorgy.me/

Dude, I used Django at 1.x - before they even had an ORM. The fact that it is adding a way to run tasks, almost a quarter of a century later, is wild to me.

I am not roasting it or anything, go Django, but just an observation.

  • I think it is refreshing. They don't half-ass things into the framework. They take the time to do it right. They let every feature fight for its life, and put their effort into LTS and minimizing number of issues and API changes related to the features they do deliver. As a developer I really appreciate this. I don't have to totally rewrite my entire application every new version because the implementation wasn't properly thought through.

    • I used to have this opinion about ASP.NET then ASP.NET Core and the great churn happened. It's finally settled down again, but boy the in-between years were chaotic.

      Not just the Framework -> Core migration itself, but the power to make breaking changes went to their heads, and they started quickly tearing up everything only to change their minds again, such as a short-lived "project.json" syntax.

      Django is exactly the technology I'd pick if I wasn't already super familiar with the .NET stack. It's got the "batteries included" feel without the chaotic confusion of a million ways to do things. It doesn't have the breaking changes churn that happens elsewhere too.

    • That is indeed - rare, and one of the reasons I am wary of heavy frameworks. You buy into its code AND its legacy.

  • Django had ORM from the very beginning. I've been using Django since 0.95 at it had ORM even back then. It was primitive but I hadn't to resort to raw SQL until much later.

    • Correction - it was an "ORM". I remember now, but it was so rudimentary and useless that I never really thought of it that way.

      Nothing wrong with that. One had to start somewhere.

Given that Python tends to produce fewer hallucinations when generated by LLMs I wonder if former Django developers using AI tools are secretly having a blast right now.

  • If Python produces less hallucinations it's not because of the syntax, it's because there's so much training data.

  • I think another ace up Django's sleeve is that it has had a remarkable stable API for a long time with very few breaking changes, so almost all blogposts about Django that the LLM has gobbled up will still be mostly correct whether they are a year or a decade old.

    I get remarkably good and correct LLM output for Django projects compared to what I get in project with more fast moving and frequently API breaking frameworks.

  • Whenever I saw people complain about LLMs writing code, I never really understood why they were so adamant that it just didn’t work at all for them. The moment I did try to use LLMs outside of Django, it became clear that some frameworks are just much easier to work with LLMs than others. I immediately understood their frustrations.

  • What a lot of people don’t know is that SWE-bench is over 50% Django code, so all of the top labs hyper optimize to perform well on it.

[flagged]

  • We don't need to bring this kind of thing up. We're not school children and most of us are technology professionals, so the meaning is clear.

    These guidelines are relevant here:

    Eschew flamebait. Avoid generic tangents. Omit internet tropes.

    Please don't pick the most provocative thing in an article or post to complain about in the thread. Find something interesting to respond to instead.

    Please don't complain about tangential annoyances—e.g. ... name collisions ... . They're too common to be interesting.

    https://news.ycombinator.com/newsguidelines.html

  • Well, https://en.wikipedia.org/wiki/Nonce_word

    It makes me sad when a secondary meaning, which does not even overcome the main meaning in usage, becomes an obstacle for the normal use of a word. It's like seeing a rainbow as a sexualized symbol not fit for children, because it also happens to be used by LGBTQ+ community. (BTW, since you're a Brit: did people stop using the word "fag" to refer to a cigarette?)

    • Yes, words have multiple meanings - but only some words are apparently worthy of censorship - which is my point.

      > did people stop using the word "fag" to refer to a cigarette?

      Yes, seems so. I've not heard that in at least a decade

    • I mean, it is sad. But unfortunately that is what happened with "master", "slave", "whitelist", and "blacklist". No reasonable person construed these as offensive or having any implications about the wider world. But there are people in our profession who are determined to take offense where none is given, and unfortunately they got their way.

      3 replies →