0
1.(0.001) SELECT COUNT(*) FROM (SELECT COUNT(DISTINCT "entities_hero"."id") AS "_hero_count", COUNT(DISTINCT "entities_villain"."id") AS "_villain_count" FROM "entities_origin" LEFT OUTER JOIN "entities_hero" ON ("entities_origin"."id" = "entities_hero"."origin_id") LEFT OUTER JOIN "entities_villain" ON ("entities_origin"."id" = "entities_villain"."origin_id") GROUP BY "entities_origin"."id") subquery; args=()

2.(0.000) SELECT COUNT(*) FROM (SELECT COUNT(DISTINCT "entities_hero"."id") AS "_hero_count", COUNT(DISTINCT "entities_villain"."id") AS "_villain_count" FROM "entities_origin" LEFT OUTER JOIN "entities_hero" ON ("entities_origin"."id" = "entities_hero"."origin_id") LEFT OUTER JOIN "entities_villain" ON ("entities_origin"."id" = "entities_villain"."origin_id") GROUP BY "entities_origin"."id") subquery; args=()


  (0.001) SELECT "entities_origin"."id", "entities_origin"."name", COUNT(DISTINCT "entities_hero"."id") AS "_hero_count", COUNT(DISTINCT "entities_villain"."id") AS "_villain_count" FROM "entities_origin" LEFT OUTER JOIN "entities_hero" ON ("entities_origin"."id" = "entities_hero"."origin_id") LEFT OUTER JOIN "entities_villain" ON ("entities_origin"."id" = "entities_villain"."origin_id") GROUP BY "entities_origin"."id" ORDER BY "entities_origin"."id" DESC; args=()

在此处输入图像描述

实体/模型.py

from django.db import models

class Category(models.Model):
    name = models.CharField(max_length=100)

    class Meta:
        verbose_name_plural = "Categories"

    def __str__(self):
        return self.name

class Origin(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Entity(models.Model):
    GENDER_MALE = "Male"
    GENDER_FEMALE = "Female"
    GENDER_OTHERS = "Others/Unknown"

    choice = (
        (GENDER_MALE, GENDER_MALE),
        (GENDER_FEMALE, GENDER_FEMALE),
        (GENDER_OTHERS, GENDER_OTHERS),
    )

    name = models.CharField(max_length=100)
    alternative_name = models.CharField(max_length=100, null=True, blank=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    origin = models.ForeignKey(Origin, on_delete=models.CASCADE)
    gender = models.CharField(max_length=100, choices=choice)
    description = models.TextField()

    def __str__(self):
        return self.name

    class Meta:
        abstract = True

class Hero(Entity):

    class Meta:
        verbose_name_plural = "Heroes"

    is_immortal = models.BooleanField(default=True)
    benevolence_factor = models.PositiveSmallIntegerField(help_text="How benevolent this hero is?")
    arbitrariness_factor = models.PositiveSmallIntegerField(help_text="How arbitrary this hero is?")
    father = models.ForeignKey("self", related_name="+", null=True, blank=True, on_delete=models.SET_NULL)
    mother = models.ForeignKey("self", related_name="+", null=True, blank=True, on_delete=models.SET_NULL)
    spouse = models.ForeignKey("self", related_name="+", null=True, blank=True, on_delete=models.SET_NULL)

class Villain(Entity):
    is_immortal = models.BooleanField(default=False)
    malevolence_factor = models.PositiveSmallIntegerField(help_text="How malevolent this villain is?")
    power_factor = models.PositiveSmallIntegerField(help_text="How powerful this villain is?")
    is_unique = models.BooleanField(default=True)
    count = models.PositiveSmallIntegerField(default=1)

实体/admin.py

@admin.register(Origin)
class OriginAdmin(admin.ModelAdmin):

    list_display = ("name","hero_count", "villain_count")

    def get_queryset(self, request):
        queryset = self.model.objects.all().annotate(
            _hero_count=Count("hero", distinct=True),
            _villain_count=Count("villain", distinct=True),
        )
        return queryset

    def hero_count(self, obj):
        return obj._hero_count

    def villain_count(self, obj):
        return obj._villain_count
4

1 回答 1

2

Django 管理员在列表页面中运行了两次 count(*) 查询。

  1. 获取对象计数。Django admin 在列表页面中显示对象计数。这可以通过docsshow_full_result_count = False提到的设置来禁用。

  2. Django 分页。Django paginator 执行 count(*) 来生成分页。对于大型表,每次运行此查询都会使页面加载速度变慢。一个快速的解决方法是将计数缓存在分页器中并重新使用。有了这个,第一次页面加载会更慢,但后续页面会加载得更快。这是django 缓存分页器的片段。

于 2020-02-19T10:44:08.477 回答