В django можно ли использовать объекты F (), чтобы увидеть, содержит ли константа строки из поля? - PullRequest
0 голосов
/ 15 сентября 2011

All
Я пытаюсь в основном делать уведомления по ключевым словам, поэтому всякий раз, когда создается объект с именем, любой, кто хочет получить уведомление о любом из слов в этом имени, будет.
например

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 () объекты для сравнения одного поля с другим, например:

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

Теперь кто-нибудь знает, как заменить первое поле постоянной строкой? Вот так:

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

Или я собираюсь сделать это задом наперед?

Ответы [ 4 ]

3 голосов
/ 30 мая 2016

Это выглядит не очень красиво, но все это можно сделать стандартными фильтрами.

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 голос
/ 15 сентября 2011

Вы не должны пытаться бороться с Django ORM. Он охватывает наиболее часто вещи, но ваш случай не тот. Просто используйте extra, чтобы получить то, что вам нужно (или даже raw).

0 голосов
/ 02 октября 2013

Попробуйте использовать '.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: я сделал собственный агрегатор, эта логика кажется правильной, потому что запрос, полученный из набора запросов, очень похож на тот, который я хотел, но, к сожалению, есть другая проблема: 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

Только что определенный пользовательский поиск «старты», который имеет обратную логику «старты с»

0 голосов
/ 15 сентября 2011

Вы можете сделать это, предоставив dict аргументов, например ::

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