Django 注释计数不起作用总是返回 1

问题描述 投票:0回答:4

我的模特:

class PicKeyword(models.Model):
    """chat context collection

    """
    keyword = models.TextField(blank=True, null=True)

我的过滤器:

from django.db.models import Count
PicKeyword.objects.annotate(Count('keyword'))[0].keyword__count

结果总是1

就像:

print(PicKeyword.objects.filter(keyword='hi').count()

显示: 3

PicKeyword.objects.filter(keyword='hi').annotate(Count('keyword'))[0].keyword__count

显示: 1

是因为我使用sqllite还是我的关键字类型是Textfield?

python django annotate
4个回答
3
投票

我遇到了完全相同的问题,但没有一个答案对我有用。 我能够使用以下语法使其工作,仅传递 1 个字段作为值(对我有用,因为我试图发现重复项):

dups = PicKeyword.objects.values('keyword').annotate(Count('keyword')).filter(keyword__count__gt=1)

以下内容始终返回一个空查询集,这不应该:

dups = PicKeyword.objects.values('keyword','id').annotate(Count('keyword')).filter(keyword__count__gt=1)

希望有帮助


2
投票

您尝试在此处注释关键字数量的方式,

PicKeyword.objects.annotate(Count('keyword'))[0].keyword__count

仅当您想要总结多个对象之间的关系时才有效。由于您没有任何与
keyword
字段相关的对象,因此输出始终为 1(它自己的实例)

正如 queryset.annotate 的 API 文档所述,

使用提供的查询表达式列表注释查询集中的每个对象。表达式可以是一个简单值、对模型(或任何相关模型)上字段的引用,或者是对与模型中的对象相关的对象进行计算的聚合表达式(平均值、总和等)。查询集。

Queryset.annotate 示例的博客模型参考

最后,如果对象之间没有关系,并且您的目标只是获取

PicKeyword

 模型中的对象数量,则 @samba 和 @Willem 的答案是正确的。


2
投票
以下将显示准确的计数:

PicKeyword.objects.annotate(Count('keyword')).count()
    

0
投票
对于没有关系的单表,需要应用不同的逻辑进行标注。

就简单的 SQL 查询而言,看起来是这样的:

假设您需要计算

user_email

 字段具有相同值的行数:

SELECT c.*, COALESCE(u.user_email_count, 0) AS user_email_count FROM your_table_name c LEFT JOIN ( SELECT user_email, COUNT(*) AS user_email_count FROM your_table_name GROUP BY user_email ) u ON c.user_email = u.user_email;
Django 中的相同查询具有以下形式:

from django.db.models import Count, OuterRef, Subquery, Value, IntegerField from django.db.models.functions import Coalesce subquery = YourModelName.objects.filter( user_email=OuterRef('user_email') ).values('user_email').annotate( user_email_count=Count('user_email') ).values('user_email_count') queryset = models.YourModelName.objects.annotate( user_email_count=Coalesce( Subquery(subquery), Value(0), output_field=IntegerField() ) )
现在,这个查询集有一个名为 

user_email_count.

 的新额外列,您的类的任何实例(如果您重新定义查询集)也将有一个新字段,
user_email_cont.
您可以在接受该实例的任何函数中引用它你的模型。以下是如何在 Django 管理面板(列表视图)中添加具有相同 user_email 的数据库行数列的示例:

from django.contrib import admin @admin.register(models.YourModelName) class YourModelNameAdmin(admin.ModelAdmin): """ Admin View of My Model """ list_display = ['field1', 'field2', 'user_email_count_field'] def user_email_count_field(self, model_instance: YourModelName): """ Returns the number of rows with the same user_email """ # Here, I return the value of this newly added field # for each instance of my model. return model_instance.user_email_count user_email_count.short_description = 'Saved_questions' def get_queryset(self, request): """ Adds annotation (extra column named user_email_count) """ // The code above for redefining a queryset subquery = ... queryset = ... return queryset
    
© www.soinside.com 2019 - 2024. All rights reserved.