Simple Subquery with OuterRef

One of the problems with your example is that you cannot use queryset.count() as a subquery, because .count() tries to evaluate the queryset and return the count. So one may think that the right approach would be to use Count() instead. Maybe something like this: Post.objects.annotate( count=Count(Tag.objects.filter(post=OuterRef(‘pk’))) ) This won’t work for two reasons: The … Read more

Django query annotation with boolean field

I eventually found a way to do this using django 1.8’s new conditional expressions: from django.db.models import Case, When, Value, IntegerField q = ( Product.objects .filter(…) .annotate(image_count=Count(‘images’)) .annotate( have_images=Case( When(image_count__gt=0, then=Value(1)), default=Value(0), output_field=IntegerField())) .order_by(‘-have_images’) ) And that’s how I finally found incentive to upgrade to 1.8 from 1.7.

Django excluding specific instances from queryset without using field lookup

The way you’re already doing it is the best way. If it’s a model-agnostic way of doing this you’re looking for, don’t forget that you can do query.exclude(pk=instance.pk). Just as an aside, if Django’s ORM had an identity mapper (which it doesn’t at present), then you would be able to do something like MyModel.objects.filter(<query>).all().remove(<instance>), but … Read more

select_related with reverse foreign keys

Yes, that is what prefetch_related() is for. It will require an additional query, but the idea is that it will get all of the related information at once, instead of once per Person. In your case: qs.select_related(‘position__report_to’) .prefetch_related(‘position__report_to__person_set’) should require two queries, regardless of the number of Persons in the original query set. Compare this … Read more

What is a Django QuerySet?

A django queryset is like its name says, basically a collection of (sql) queries, in your example above print(b.query) will show you the sql query generated from your django filter calls. Since querysets are lazy, the database query isn’t done immediately, but only when needed – when the queryset is evaluated. This happens for example … Read more

Django Order By Date, but have “None” at end?

Django 1.11 added this as a native feature. It’s a little convoluted. It is documented. Ordered with only one field, ascending: wo = Work_Order.objects.order_by(F(‘dateWORequired’).asc(nulls_last=True)) Ordered using two fields, both descending: wo = Work_Order.objects.order_by(F(‘dateWORequired’).desc(nulls_last=True), F(‘anotherfield’).desc(nulls_last=True))

Django Aggregation: Summation of Multiplication of two fields

With Django 1.8 and above you can now pass an expression to your aggregate: from django.db.models import F Task.objects.aggregate(total=Sum(F(‘progress’) * F(‘estimated_days’)))[‘total’] Constants are also available, and everything is combinable: from django.db.models import Value Task.objects.aggregate(total=Sum(‘progress’) / Value(10))[‘total’]

Django ORM – objects.filter() vs. objects.all().filter() – which one is preferred?

The method all() on a manager just delegates to get_queryset(), as you can see in the Django source code: def all(self): return self.get_queryset() So it’s just a way to get the QuerySet from the Manager. This can be handy to ensure that you’re dealing with a QuerySet and not a Manager, because MyModel.objects returns a … Read more