django admin list_display 带有计数注释

nas*_*jai 3 python django django-orm django-admin

我想将“注释计数”字段添加到 Django Admin 中的 list_display 中。

模型.py

class Log(models.Model):
    ...
    ip_address = models.GenericIPAddressField(
        verbose_name=_('IP address'),
        db_index=True,
    )
    ...
Run Code Online (Sandbox Code Playgroud)

管理员.py

class LogAdmin(admin.ModelAdmin):
    list_display = (..., 'ip_address', 'ip_address_count', ...)

    def ip_address_count(self, instance):
        return models.Log.objects \
            .filter(ip_address=instance.ip_address) \
            .count()

    ip_address_count.short_description = _('IP Address Count')
Run Code Online (Sandbox Code Playgroud)

它可以很好地处理“大量”SQL 查询。

admin.py我想像这样改进我的:

class Log(models.Model):
    ...

    def get_queryset(self, request):
        qs = super(LogAdmin, self).get_queryset(request)
        qs = qs.values('ip_address') \
               .annotate(ip_address_count=Count('ip_address'))
        return qs

    def ip_address_count(self, instance):
        return instance.ip_address_count
Run Code Online (Sandbox Code Playgroud)

但是,我遇到了错误消息:

'dict' object has no attribute '_meta'

看来我找到了错误发生的原因:

Django 管理员,无法分组依据:异常值:“dict”对象没有属性“_meta”

然而,这并不能帮助我解决问题。

谢谢您的回答。

编辑:如果我不附加 ,它就会出错.values('ip_address)

它不是group by ip_address。因此,group by所有字段group by field1, field2, ip_address, ...的结果都是“1”。

小智 6

以下是您可以如何在本地进行操作。Django 知道如何处理这个问题(请参阅有关admin 和 list_display的文档)。

class LogAdmin(admin.ModelAdmin):
    list_display = (..., "field1", "field2"... "quantity_of_things",)

    def get_queryset(self, request):
        return (super(LogAdmin, self).get_queryset(request).annotate(quantity_of_things=Count("xxxxxx")))

    def quantity_of_things(self, obj):
        return obj.quantity_of_things
    quantity_of_things.short_description = "Number of xxxxxx"
Run Code Online (Sandbox Code Playgroud)

Count您可以使用所需的任何内容(例如a)来注释查询集。如您所见,您只需使用相同的名称 3 次(quantity_of_things在我的示例中)

  1. 在 list_display 中(Django 知道这是一个可调用的),
  2. 在注释中,
  3. 在要调用的函数中。
  4. quantity_of_things.short_description用于列标题