django queryset中的Modulo?

xzlaal3s  于 2023-08-08  发布在  Go
关注(0)|答案(2)|浏览(129)

在django queryset中是否已经有一种根据id % 4 == 0选择对象的方法?
到目前为止,我找到的唯一解决方案是编写一个自定义转换,因为PostgreSQL似乎支持模,但我得到了错误。
下面是我的代码:

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)

字符串
当查询集被求值时,我得到一个错误(用foos.count()或其他什么):

IndexError: tuple index out of range


引用一个Django文件。这似乎是由于模,因为我设法使自定义转换与文档的例子工作。
你有什么想法吗?

kxkpmulp

kxkpmulp1#

我手头上没有Django 1.8来测试它,但看起来你可以使用F和注解来做到这一点,就像这样:

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

字符串
(Django 1.7及更早版本不支持在annotate中使用F)
对于Django 1.7和更早版本,你可以使用.extra(),但它不是很漂亮:

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

368yc8dk

368yc8dk2#

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

字符串
我不明白你在问什么,但是在我使用的django4中

return "%s %% 4 = 0" % lhs, params


应该是,

return "%s %%%% 4 = 0" % lhs, params


因为%字符串将被插入两次,一次在as_mysql中,另一次在db游标中,所以对于sql语句'%'变成'%',这是模数运算。这种行为在大多数django类中都是一样的,这些类提供了创建自定义SQL模板的功能

相关问题