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

Django 1.11如何整合auth.models与自定义Model字段?

最优实现方案:在User Admin中展示所有用户的Response提交状态

你想要在Django Admin的用户列表里显示全部注册用户,同时关联他们的Response模型中的created字段(包括未提交过响应的用户),这个需求可以通过Django的annotate结合Subquery来高效实现,避免常见的N+1查询性能问题,具体步骤如下:

1. 核心思路

我们需要给User的查询集添加一个注解字段,用来关联每个用户对应的最新(或最早)Response的created时间。通过Subquery可以在一次数据库查询中完成关联,而不需要为每个用户单独发起查询。

2. 修改Admin代码

更新你的survey/admin.py文件,代码如下:

from django.contrib import admin
from django.contrib.auth.models import User
from django.db.models import Subquery, OuterRef
from survey.models.response import Response

# 先取消默认的User注册
admin.site.unregister(User)

class UserAdmin(admin.ModelAdmin):
    # 把自定义的字段加入列表展示
    list_display = ('username', 'response_submit_time')
    
    def get_queryset(self, request):
        # 子查询:获取每个用户最新的Response记录的created时间
        latest_responses = Response.objects.filter(
            user=OuterRef('pk')
        ).order_by('-created')  # 按创建时间倒序,取最新的一条
        
        # 给User查询集添加注解字段
        return super().get_queryset(request).annotate(
            _latest_response_created=Subquery(latest_responses.values('created')[:1])
        )
    
    def response_submit_time(self, obj):
        # 处理未提交过响应的用户,显示友好提示
        return obj._latest_response_created if obj._latest_response_created else "未提交"
    
    # 设置列表表头的显示名称
    response_submit_time.short_description = '响应提交时间'

# 重新注册自定义的UserAdmin
admin.site.register(User, UserAdmin)

3. 方案优势

  • 覆盖所有用户:不管用户有没有提交过Response,都会出现在列表中,未提交的用户会显示“未提交”,完美满足你查看「谁没提交」的需求。
  • 性能高效:通过Subquery实现一次关联查询,避免了为每个用户单独查询Response的N+1性能问题,即使是200个用户也能快速加载。
  • 灵活可扩展:如果想展示最早的提交时间,只需要把order_by('-created')改成order_by('created')即可;如果需要展示其他Response字段,也可以用同样的方式扩展。

为什么不推荐其他方式?

如果直接在response_submit_time方法中通过obj.response_set.first().created获取时间,会导致每个用户加载时都发起一次额外的数据库查询,当用户数量多的时候,性能会明显下降,这也是我们优先选择annotate+Subquery的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:28:58