Django 管理后台列表显示优化 queryset

5
User模型中,我有一个方法:
@cached_property
    def income(self):
        return PartnerIncome.objects.all().aggregate(Sum('income'))['income__sum']*self.share_of_profit

合作伙伴收入模型:

class PartnerIncome(models.Model):
    title = models.CharField(max_length=255)
    income = models.FloatField(default=0)

现在我想在管理面板中显示“收入”('income'),但每个对象都会向数据库发出额外的查询。我该如何将PartnerIncome.objects.all().aggregate(Sum('income'))作为全局变量用于管理列表,以避免这种情况的发生...

有时候我会使用原始的 SQL 来进行行级别的聚合字段操作,这样做速度更快,而且数据库通常会缓存。另外一个技巧是创建另一个聚合模型来保存总收入(以及可能的其他聚合字段),并在 PartnerIncome 信号上更新该字段(删除旧的收入并添加新的收入)。 - Saikiran Yerram
1个回答

9

你可以在ModelAdmin中重写get_queryset方法,怎么样?

class UserAdmin(admin.ModelAdmin):

    list_display = ('income', ...)

    def income(self, obj):
        return obj.income

    def get_queryset(self, request):
       queryset = super(UserAdmin, self).get_queryset(request)
       # you logic here to `annotate`the queryset with income
       return queryset

聚合文档:

https://docs.djangoproject.com/en/dev/topics/db/aggregation/

如果我不了解您的模型和业务逻辑,这里是我的代码片段示例:

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('__str__', 'books_count',)

    def books_count(self, obj):
        return obj.books_count

    def get_queryset(self, request):
        return super(AuthorAdmin, self).get_queryset(
            request).annotate(books_count=Count('books'))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接