【问题标题】:How does django implement double underscore in filter?django如何在过滤器中实现双下划线?
【发布时间】:2017-03-02 00:22:40
【问题描述】:

我注意到Django 使用双下划线在Model.objects.filter 实例中定义lookup

例如:

Room.objects.filter(width__lte = 10)

它是如何工作的?如何创建自己的函数,如 Django 并知道 width__lte 实际上是为 widthlower then or equal to 10 分开的。

【问题讨论】:

  • 这里只是一个猜测:但.filter 接受**kwargs 然后他们解析相应的k,v 对,其中k,在这种情况下将是字符串“width__lte”跨度>
  • 过滤器正在使用**kwargs,这是正确的。但我的问题是他们是如何解析双倍分数的,他们是如何实现的?
  • 方法有很多种。您可以简单地拆分 "__" 并从那里处理。很可能,或者至少我希望,他们使用了更复杂的东西。
  • 我确定有很多方法,我想知道它在Django中是如何实现的,我在Django代码中找不到它
  • github.com/django/django/blob/…中搜索LOOKUP_SEP

标签: python django django-models syntax


【解决方案1】:

Django 1.10 Documentation 关于自定义查找:

仔细看一下实现,第一个必需的属性是lookup_name。这允许 ORM 了解如何解释 name__ne 并使用 NotEqual 生成 SQL。按照惯例,这些名称总是只包含字母的小写字符串,但唯一的硬性要求是它不能包含字符串 __。

来自其他来源:

查找:这些基本上是“查询的 WHERE 子句中的一个条件”。 django 中的例子是lt, gt, gte, contains 等等。要创建自定义查找,请将 models.Lookup 子类化。您设置 lookup_name 并实现 .as_sql() 方法。然后为它有效的各种字段类型注册它。

您可以阅读更多here

我也引用this answer:

from django.db.models import Lookup

class AbsoluteValueLessThan(Lookup):
    lookup_name = 'lt'

    def as_sql(self, qn, connection):
        lhs, lhs_params = qn.compile(self.lhs.lhs)
        rhs, rhs_params = self.process_rhs(qn, connection)
        params = lhs_params + rhs_params + lhs_params + rhs_params
        return '%s < %s AND %s > -%s' % (lhs, rhs, lhs, rhs), params

AbsoluteValue.register_lookup(AbsoluteValueLessThan)

注册时,您可以直接使用Field.register_lookup(AbsoluteValueLessThan)

从 stackoverflow 本身我得到了 django 双下划线 __ 的含义。 Have a look here.

【讨论】:

  • 谢谢,但我仍然有一个缺失的部分 - Django 如何在双下划线后获得 lookup_name
  • @OzBar-Shalom 我猜这是 Django 功能,它告诉它在找到双下划线时进行查找。我已经从 django 文档中添加了对此的解释。我希望这能解决您的问题。
【解决方案2】:

感谢下面的答案,我找到了问题的答案:

Django 有一个 const LOOKUP_SEP = '__' 然后使用 split 将参数拆分为键值对

【讨论】:

    猜你喜欢
    • 2013-02-03
    • 2020-03-12
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 2016-08-02
    • 2016-04-25
    相关资源
    最近更新 更多