【问题标题】:How to OR a raw filter with django ones如何使用 django 或原始过滤器
【发布时间】:2012-06-29 19:32:48
【问题描述】:

我为标题道歉。

我需要使用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 对象和 OR (|) 它与 Q 对象

【问题讨论】:

    标签: django django-queryset django-orm


    【解决方案1】:

    我设法找到了解决方案。

    我继承了django.db.models.Q 并实现了add_to_query(self, query, alias) 方法。这样我就可以ORAND Qs 没有任何问题。

    示例代码:

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

    你真的应该添加额外的位(例如支持链 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)
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-24
      • 2012-05-12
      • 2016-09-23
      • 2020-05-01
      • 1970-01-01
      相关资源
      最近更新 更多