【问题标题】:Django annotate StrIndex for empty fieldsDjango为空字段注释StrIndex
【发布时间】:2020-11-03 00:59:48
【问题描述】:

我正在尝试使用 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)?

【问题讨论】:

  • 不应该交换参数,所以idx=StrIndex('user', models.Value('xxxx'))?第一个参数是“干草堆”,第二个是“针”。

标签: django orm django-orm


【解决方案1】:

只过滤user 为空的行:

(~models.Q(user='') & models.Q(idx__gt=0)) | models.Q(domain='spamdomain.co.uk')

【讨论】:

    【解决方案2】:

    StrIndex [Django-doc]的参数顺序交换。第一个参数是haystack,你在其中搜索的字符串,第二个参数是needle,你正在寻找的子字符串。

    因此您可以使用以下方式进行注释:

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

    【讨论】:

      猜你喜欢
      • 2014-05-18
      • 2018-04-25
      • 1970-01-01
      • 2019-07-21
      • 2021-02-08
      • 2020-09-03
      • 2019-01-22
      • 2019-09-03
      • 2017-12-06
      相关资源
      最近更新 更多