I want to filter for Django objects such that their "id modulo K == N" .
Here's a way to do it in python, but I want it in the filter():
for foo in Foo.objects.all():
if foo.id % K == N:
print foo
So, I can use extra() with a query like this (please correct me if I'm wrong):
Foo.objects.extra(where['id %% %s = %s' % (K,N)])
But is there a way to use F()?
Django supports the use of addition, subtraction, multiplication, division and modulo arithmetic with F() objects
Note: this is very wrong:
Foo.objects.filter(id=F('id') % K)
I would need something like:
Foo.objects.filter(id__mod(K)=N)
F() expressions. An F() object represents the value of a model field, transformed value of a model field, or annotated column. It makes it possible to refer to model field values and perform database operations using them without actually having to pull them out of the database into Python memory.
In the Django QuerySet API, F() expressions are used to refer to model field values directly in the database.
The gte lookup is used to get records that are larger than, or equal to, a specified value. For a greater than, but not or equal to, search, use the gt lookup.
Django offers a QuerySet method called select_related() that allows you to retrieve related objects for one-to-many relationships. This translates to a single, more complex QuerySet, but you avoid additional queries when accessing the related objects. The select_related method is for ForeignKey and OneToOne fields.
Django 1.8 allows you to use F() objects in annotations. The syntax is:
Foo.objects.annotate(id_mod=F('id') % K).filter(id_mod=n)
The feature was implemented in #14030. For earlier versions of Django, you can use extra()
.
If you think about what filter is trying to do, it's taking an attribute and performing a comparison. You aren't actually comparing id
to anything, but rather are filtering based off a calculated value. extra
is the most appropriate way to perform this calculation-based filtering despite it sounding like filter
would be able to do that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With