You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django Admin中按模型@property属性对对象进行排序?

要在Django Admin里按这个completed_this_month属性排序,你得先明白一个关键点:原生的@property是Python层面计算的,数据库根本不知道这个值,所以没法直接用来排序。Django Admin的排序是基于数据库查询的,所以我们得把这个统计逻辑移到数据库层面,用annotate来实现,然后让Admin用这个数据库层面的注解字段来排序。

下面是具体的实现步骤,结合你的代码来修改:

首先,导入需要的模块:

from django.contrib import admin
from django.db.models import Count, Q
from django.utils import timezone
from django.db.models.functions import TruncMonth
from .models import Worker, Task

然后修改你的WorkerAdmin类:

class WorkerAdmin(admin.ModelAdmin):
    # 把你的其他字段和completed_this_month一起放到list_display里
    list_display = ('username', 'name', 'completed_this_month')  # 替换成你实际的字段

    def get_queryset(self, request):
        # 获取当前时间(用Django的timezone避免时区问题)
        today = timezone.now()
        
        # 调用父类的queryset,然后给每个Worker注解本月完成的任务数
        qs = super().get_queryset(request).annotate(
            # 这里的`tasks`是Task模型中外键指向Worker的related_name
            # 如果你的Task外键没设置related_name,默认是`task_set`,记得改成对应的名称
            _completed_this_month=Count(
                'tasks',
                # 过滤条件:本月完成的任务
                filter=Q(completed_on__truncmonth=TruncMonth(today)),
                distinct=True  # 防止重复统计,根据你的关联关系可选
            )
        )
        return qs

    def completed_this_month(self, obj):
        # 直接返回注解好的值,不用再单独查数据库(解决原来的N+1查询问题)
        return obj._completed_this_month
    
    # 关键:指定这个显示字段的排序依据是我们注解的数据库字段
    completed_this_month.admin_order_field = '_completed_this_month'
    # 给这个字段设置显示名称(可选)
    completed_this_month.short_description = '本月完成任务数'

几个需要注意的点:

  • 关联名称:如果你的Task模型里的外键是worker = models.ForeignKey(Worker, on_delete=models.CASCADE),没有设置related_name,那上面的'tasks'要改成'task_set',否则会报错。如果设置了related_name='tasks',就用'tasks'。
  • 时区问题:用timezone.now()代替datetime.date.today(),确保和Django的时区设置一致,避免统计日期出错。
  • 性能优化:原来的@property会导致每个Worker实例都单独查一次数据库(N+1查询),用annotate后只需要一次查询就统计完所有Worker的任务数,性能提升很多。
  • 保留原@property:如果你在其他地方还需要用原来的@property,可以保留它,Admin里我们用重写的completed_this_month方法就好,互不影响。

这样修改后,你在Worker Admin页面点击本月完成任务数的表头,就能正常排序啦!

内容的提问来源于stack exchange,提问作者Greg K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:39:18