Django аннотировать StrIndex для пустых полей - PullRequest
2 голосов
/ 13 июля 2020

Я пытаюсь использовать Django StrIndex, чтобы найти все строки со значением, являющимся подстрокой данной строки.

Например: моя таблица содержит:

+----------+------------------+
|   user   |      domain      |
+----------+------------------+
| spam1    | spam.com         |
| badguy+  |                  |
|          | protonmail.com   |
| spammer  |                  |
|          | spamdomain.co.uk |
+----------+------------------+

, но запрос

SpamWord.objects.annotate(idx=StrIndex(models.Value('xxxx'), 'user')).filter(models.Q(idx__gt=0) | models.Q(domain='spamdomain.co.uk')).first()

соответствует <SpamWord: *@protonmail.com>

Это запрос SELECT `spamwords`.`id`, `spamwords`.`user`, `spamwords`.`domain`, INSTR('xxxx', `spamwords`.`user`) AS `idx` FROM `spamwords` WHERE (INSTR('xxxx', `spamwords`.`user`) > 0 OR `spamwords`.`domain` = 'spamdomain.co.uk')

Это должно быть <SpamWord: *@spamdomain.co.uk>

это происходит, потому что INSTR('xxxx', '') => 1 (а также INSTR('xxxxasd', 'xxxx') => 1, что правильно)

Как мне написать этот запрос, чтобы получить запись №5 (spamdomain.co.uk)?

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Просто фильтруйте строки, где user пусто:

(~models.Q(user='') & models.Q(idx__gt=0)) | models.Q(domain='spamdomain.co.uk')
0 голосов
/ 13 июля 2020

Меняется порядок параметров StrIndex [Django -doc] . Первый параметр - это стог сена , строка, в которой вы ищите, а второй - игла , подстрока, которую вы ищете.

Таким образом, вы можете аннотировать:

from django.db.models import Q, Value

SpamWord.objects.annotate(
    idx=<b>StrIndex('user', Value('xxxx'))</b>
).filter(
    Q(idx__gt=0) | Q(domain='spamdomain.co.uk')
).first()
...