如何使用django的原始过滤器

时间:2012-06-28 09:44:33

标签: django django-queryset django-orm

我为标题道歉。

我需要使用to_char(或类似的东西)将日期时间字段转换为字符串,并在进行查询时对其应用ILIKE

这样的事情:

SELECT ...

FROM mytable
WHERE 
    mytable.type = 'mytype'
 AND (
        mytable.name = 'myname' 
        OR 
        to_char(created_at, 'Mon DD, YYYY, MI:SS') ILIKE '%jun 27,%'
    )

正如您所看到的,问题是查询的这一部分必须 OR 包含一些过滤器, AND 包含其他过滤器。

考虑:

  • 我无法使用extra(select=...)将字段转换为字符串,然后使用filter(..)对其进行过滤,因为django不支持
  • 我无法使用extra(where=...)因为 OR 整个查询
  • 我无法使用ExtraWhere对象创建Q对象和 OR (|)

1 个答案:

答案 0 :(得分:3)

我设法找到了解决方案。

我将django.db.models.Q子类化并实施了add_to_query(self, query, alias)方法。通过这种方式,我可以毫无问题地 OR AND

示例代码:

请注意这只是一个简化版本,这里只是为了给您一个想法。

你应该添加额外的位(例如支持链myobj_ my2ndobj _my3rdobj__mydatetime_field)

from django.db.models import Q
from django.db.models.sql.where import ExtraWhere, OR

class DatetimeQ(Q):
    def __init__(self, *args, **kwargs):
        super(DatetimeQ, self).__init__(*args, **kwargs)
        self.name = kwargs.get('name')
        self.value = kwargs.get('value')

    def add_to_query(self, query, alias):
        where = ExtraWhere(["to_char(" + self.name + ", %s) ILIKE %s"], [
                'Mon DD, YYYY, MI:SS', "%%%s%%" % self.value
            ])
        query.where.add(where, OR)

希望这有帮助。