2015-05-18 4 views
4

Есть ли способ выбрать объекты в соответствии с id % 4 == 0 в django queryset?Modulo в django queryset?

Единственное решение, которое я нашел до сих пор, заключается в том, чтобы написать пользовательское преобразование, поскольку, по-видимому, в Postgresql поддерживается modulo, но у меня есть ошибки.

Вот мой код:

from django.db.models import Lookup, Transform 
from django.db.models.fields import Field, IntegerField, AutoField 

class Modulo4(Transform): 
    lookup_name = 'modulo4' 

    def as_sql(self, compiler, connection): 
     lhs, params = compiler.compile(self.lhs) 
     return "%s %% 4" % lhs, params 

AutoField.register_lookup(Modulo4) 

foos = Foo.filter(id__modulo4=0) 

И я получаю ошибку, когда QuerySet оценивается (с foos.count() или любой другой):

IndexError: tuple index out of range 

отсылая в файл Джанго. Кажется, это связано с модулем, так как мне удается сделать работу с пользовательским преобразованием с помощью doc example.

Любая идея о том, как достичь этого?

ответ

5

У меня нет Django 1.8 под рукой, чтобы проверить это, но похоже, что вы можете сделать это с помощью F with annotation, как это:

Foo.objects.annotate(idmod4=F('id') % 4).filter(idmod4=0) 

(Django 1.7 и более ранних версий не поддерживает использование F в annotate)


Для Django 1.7 и более ранних версий, вы всегда можете использовать .extra(), но это не очень красиво:

Foo.objects.extra(where=["id %% %s = 0"], params=[4]) 
+0

К сожалению, я бегу с django 1.7 :((должен был указать его в вопросе) – stellasia

+0

@stellasia обновил мой ответ единственным методом, доступным для Django 1.7 –

+0

Кажется, что не работает с параметрами% d, но я могу это сделать без опции. Большое спасибо! – stellasia