【问题标题】:Django query count wrongDjango 查询计数错误
【发布时间】:2017-04-07 18:28:14
【问题描述】:

我有一个模型(这里称为 MyModel

MyModel.objects.filter(value__exact='').delete()

删除所有带有空白value 的对象(value 是带有blank=True 的TextField)。 但是,当我这样做时,似乎消失的对象比我删除之前得到的计数要多

MyModel.objects.filter(value__exact='').count()

如果我用循环计算空白值 MyOModel 对象,使用

count = 0
for obj in MyModel.objects.iterator():
    if not obj.value or obj.value.strip() == '':
        count += 1

与上述数量相比,我只得到很少的额外物品。

是什么原因造成的?

我已经检查了引用 MyModel 的相关模型是否可以级联并以某种方式删除没有空白值的 MyModel 实例。事实并非如此。

我使用的是 Django 1.8.7。

更新

为了增加我现在尝试在 for 循环中删除的神秘感:

count = 0
for attribute_value in AttributeValue.objects.filter(value__exact=''):
    attribute_value.delete()
    count += 1

count 变量与预期数量的已删除 MyModel 对象一起出现,但仍然

MyModel.objects.filter(value__exact='').count()

结果比预期的要少。事实上,删除的对象数量似乎是预期的三倍以上。

我还尝试了以下计数(参见 cmets)

MyModel.objects.filter(value='').count()
MyModel.objects.filter(value=u'').count()

计数结果相同。

【问题讨论】:

  • 请注意,删除后 Django 返回的数字是被删除的对象相关对象的计数。也许这就是让您感到困惑的原因。
  • 查询检查空字符串。它不会自动从行值中去除空格。
  • if not obj.value or obj.value.strip() == '' 这还包括仅包含空格的字符串以及None,如果可能的话。
  • 请提供minimal reproducible example。在不知道您的实际数据的情况下,很难知道这里发生了什么。
  • @lucasnadalutti 我检查了删除操作前后MyModel.objects.count() 的差异;)

标签: python django django-models django-queryset


【解决方案1】:

这将解决您的问题

from django.db.models.functions import Length

获取所有包含某些内容的值字段

MyModel.objects.annotate(value_length=Length('value')).filter(value_length=0)

获取所有不为空的值

MyModel.objects.annotate(value_length=Length('value')).filter(value_length__gt=0)

你也可以这样做

MyModel.objects.filter(value='',value__isnull=True)

【讨论】:

  • 您的第一个选项似乎过于复杂。关于您的第二个选项,value 不可为空,您需要使用Q 对象来发出逻辑or
【解决方案2】:

我在另一个模型中找到了罪魁祸首,其中 MyModel 有一个未被注意的外来词。我没有看到的原因是我的设置中的这个模型也是MyModel 的引用,而 PyCharm 不知何故错过了这个关系(或者我在 PyCharm GUI 中做了)。刚刚发布的新版 PyCharm 已经帮我解决了。

很抱歉给您带来了困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    相关资源
    最近更新 更多