Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modulus Query in Django using F()

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)

like image 217
Jeff Hoye Avatar asked Nov 12 '13 23:11

Jeff Hoye


People also ask

How do you use the F expression in Django?

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.

What does F mean in Django?

In the Django QuerySet API, F() expressions are used to refer to model field values directly in the database.

What is __ GTE in Django?

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.

What is Select_related in Django?

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.


2 Answers

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().

like image 127
Alasdair Avatar answered Dec 06 '22 16:12

Alasdair


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.

like image 27
Tim Edgar Avatar answered Dec 06 '22 16:12

Tim Edgar