News for hackers. Stuff that matters.
Re:Harmful Defaults in Django by aosaigh on Friday January 07, 2022 @04:14AM (#29836890)
As someone has used Django extensively over the last 10 years for countless projects, I think that these are exaggerated claims of “harmful” defaults, particularly examples 2 to 6.

Furthermore, this:

> As you can see, Django doesn’t have your best interest at heart. Instead of providing sane defaults, it punishes you for not being a master at the framework.

Is just nonsense.

Regarding 1. While this is certainly an issue, it’s an issue for anyone using any framework and a challenge of database-backed web applications everywhere. It’s also heavily documented by Django and one of the first things mentioned. Lazy querysets are actually very useful when you need to build queries over a number of steps. Explicit query sets can have their own subtle issues with performance.

2. The default user model is fine for most users. It’s not a bad default and there is clear documentation on how to extend it. It’s designed to be extended!

3. I rarely rename migrations. Maybe this is a good idea, but it’s hardly a harmful default.

4. I almost never rename my tables. Again, maybe a sensible suggestion, not a harmful default.

5. Strangely this seems to be the most un-Django suggestion that would have the largest effect on a project but hardly any detail is given here. I never do this and wouldn’t recommend anyone else to when staring off.

6. I think project structure and CLI is one place where Django is weak but again this is hardly a harmful default. Use django-cookiecutter.

Anyway I feel like the author is trying to manufacturer controversy to help define their expertise (not to say they aren’t a good Django developer, I have no idea). Some of these are good suggestions and “top tips” but they’re certainly not instances of Django trying to harm you.

Re:Harmful Defaults in Django by spookylukey on Friday January 07, 2022 @04:49AM (#29837171)
The default user model is fine, but I *always* start a project by extending it, for future-proofing. If you need to add to it, this is *so* much better than having to add a one-to-one, and at *some* point down the line you find you do want to add something. The problem is that doing it later when you need it is a pain, because of poor support by the migrations framework.

It's like 4 lines of code that saves you so much grief later on:

    from django.contrib.auth.models import AbstractUser
    class User(AbstractUser):
        pass

    AUTH_USER_MODEL = "myapp.User"

If you never need it, those 3 lines are not hurting you. In terms of a default, I think it probably would be nicer if Django pushed you to do this up front.
Re:Harmful Defaults in Django by cessor on Friday January 07, 2022 @05:07AM (#29837327)
I agree 100%. Even if you don't need it, these lines don't hurt you, but most of the time, the additional model is put to good use. I usually add metadata, such as additional timestamps, flags, tags, custom user settings, consent or preferences.
Re:Harmful Defaults in Django by yxhuvud on Friday January 07, 2022 @06:02AM (#29837687)
> Regarding 1. While this is certainly an issue, it’s an issue for anyone using any framework and a challenge of database-backed web applications everywhere.

No, there are frameworks out there that doesn't allow queries during template rendering. See Lucky for an example, https://luckyframework.org/.

Re:Harmful Defaults in Django by Nextgrid on Friday January 07, 2022 @06:51AM (#29838008)
The problem is not whether the queries are ran in templates or in code, it's which queries are ran. Doing the same he did in the template but in code (by constructing a dictionary of items to be passed to the template) will have exactly the same problem.

The solution of using eager loading has nothing to do with whether you run your query in the template or in code.

Re:Harmful Defaults in Django by jmconfuzeus on Friday January 07, 2022 @08:21AM (#29838751)
It's easier to notice expensive SQL queries in the view vs in the template.

Anyone who claims that it's fine to run queries in templates has smoked something really good. Personally, I'll continue to aggregate all my data using JOINs before presenting them.

Re:Harmful Defaults in Django by Nextgrid on Friday January 07, 2022 @08:49AM (#29839045)
When it comes to "queries" keep in mind that I'm not saying you should call "Model.objects.filter(...)" in the template (in fact that would be very difficult to do unless you pass a "Model" reference to the template). You still do that in code.

However due to how Django handles queries by default, calling the ORM won't actually execute the query until the queryset is evaluated in most cases (unless requesting a single object or doing an aggregation), so your queries are still technically "ran" from the template - even if you are doing prefetch_related.

I personally don't have a problem with that; explicitly casting the queryset to a list before rendering a template seems like unnecessary boilerplate and still doesn't actually isolate you from the "N+1" queries problem if your template then accesses an object's relation that hasn't been prefetched.

Re:Harmful Defaults in Django by jmconfuzeus on Friday January 07, 2022 @09:04AM (#29839195)
That's the point. Instead of worrying about whether you're accessing a related attribute, join everything and evaluate the QuerySet before passing it to context.

You'll never have to worry about whether {{ pizza.topping.name }} is hitting the database ever again, especially, if you install django-zen-queries because it will raise an exception if you try to.

Re:Harmful Defaults in Django by Nextgrid on Friday January 07, 2022 @10:14AM (#29840036)
Got it - so the magic here isn't merely to evaluate querysets ahead of time (which can still return objects with unfetched relations that'll cause a query at runtime if accessed) but to also rely on the third-party package to explicitly disallow that.
Re:Harmful Defaults in Django by jmconfuzeus on Friday January 07, 2022 @12:12PM (#29841694)
It's highly unlikely that will you execute unnecessary queries from view code because usually you'll have a context like {"pizzas": page_obj.object_list}. You'll almost never execute something like:

  for pizza in pizzas:
      print(pizza.topping.name)
But you'll certainly do the following in templates:

  {% for pizza in pizzas %}
    <p>{{ pizza.topping.name }}</p>
  {% endfor %}
I also don't understand why you want to avoid 3rd party packages, especially if it helps you write better code.
Re:Harmful Defaults in Django by Nextgrid on Sunday January 09, 2022 @03:07AM (#29861330)
My argument was that the third-party package is what's key here. Merely converting your querysets to a list in code before handing it off to the template won't fully protect you against extra queries.

I'm not necessarily trying to avoid third-party packages, in fact I've installed the package you suggested in one of my projects and will be trying it out.

Re:Harmful Defaults in Django by jmconfuzeus on Friday January 07, 2022 @09:10AM (#29839255)
Nothing I wrote is controversial. I explained my thought process at length but you flat out rejected everything without explaining why. I wonder who's creating controversy here.