在django中,可以使用F()对象来查看常量是否包含字段中的字符串?

时间:2011-09-15 17:36:58

标签: django django-models django-queryset

全部,
   我正在尝试基本上执行关键字通知,因此每当创建具有名称的对象时,任何想要通知此名称中的任何单词的人都将是。
例如

Records:
   keyword: Hello
   keyword: World

New Name: "Hello World"

Returns both records


我在sqlite中创建了一个正确适用于此的查询,我知道如何跨数据库进行翻译。

SELECT * FROM table t
WHERE "a constant string" LIKE "%" || t.field || "%";

我已经确定在django中,可以使用F() objects将一个字段与另一个字段进行比较,如下所示:

Entry.objects.filter(n_comments__gt=F('n_pingbacks'))

现在有人知道如何用常量字符串替换第一个字段吗?像这样:

Entry.objects.filter("constant string"__icontains=F('n_pingbacks'))

或者我是否会倒退呢?

4 个答案:

答案 0 :(得分:3)

它看起来并不特别漂亮,但可以使用标准过滤器完成。

from django.db.models import ExpressionWrapper, CharField, Value

Entry.objects.annotate(
    my_const=ExpressionWrapper(Value("a constant string"),
                               output_field=CharField())
).filter(my_const__contains=F('n_pingbacks'))

答案 1 :(得分:1)

你不应该尝试与django ORM战斗。它涵盖了最常见的事情,但你的情况不是那个。只需使用extra即可获得所需内容(甚至是raw)。

答案 2 :(得分:0)

您可以通过提供dict个参数来完成此操作,例如:

Entry.objects.filter(**{("%s__icontains" % constant_string):F('n_pingbacks')})

答案 3 :(得分:0)

尝试使用'.extra'选择const作为字段,而不是使用myconst__contains,例如:

queryset.extra(select={'myconst': "'this superstring is myconst value'"}).filter(myconst__contains=F('myfield'))

不要忘记在双重标记内的撇号中加入常量值。

但是,有人会帮我把它放进Q对象吗? =)

UPD: 突然,由于以下问题,它失败了: https://code.djangoproject.com/ticket/13363

也许,他们会解决它。

UPD:你可以按照添加'.annotate'的字段进行过滤,但我不知道,如何在此处放置常量而不是聚合。也许,创建自定义聚合函数,就像这里: http://coder.cl/2011/09/custom-aggregates-on-django/

UPD:我做了自定义聚合器,这个逻辑似乎是正确的,因为我从queryset获得的查询与我想要的非常相似,但不幸的是,还有另一个问题:16731(抱歉没有提供完整的url ,没有足够的代表,看到上面的另一张票。)

UPD(最后):我已经设法使用以下的monkeypatching:

  1. django.db.models.sql.Query.query_terms
  2. django.db.models.fields.Field.get_prep_lookup
  3. django.db.models.fields.Field.get_db_prep_lookup
  4. django.db.models.sql.where.WhereNode.make_atom
  5. 刚刚定义的自定义查找'starts',它具有'startswith'的反向逻辑