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

如何在Django Admin中重写新增字段集QuerySet并优化权限查询

解决Django Admin新增用户时权限查询过多的问题

核心方案:自定义用户创建表单,预取权限关联数据

1. 自定义用户创建表单

继承Django内置的UserCreationForm,在表单初始化时重写permissions字段的查询集,通过select_related预取权限关联的content_type——这是触发大量N+1查询的核心原因,默认加载权限时会逐个查询对应的ContentType。

示例代码:

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User, Permission

class CustomUserCreationForm(UserCreationForm):
    class Meta:
        model = User
        fields = UserCreationForm.Meta.fields + ('permissions',)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 预取权限关联的content_type,将查询量从数百次压缩到1-2次
        self.fields['permissions'].queryset = Permission.objects.select_related('content_type').order_by('name')

2. 在UserAdmin中绑定自定义表单

自定义UserAdmin类(或修改已有类),将add_form属性指定为上面的自定义表单,同时确保新增用户的字段集包含permissions。

示例代码:

from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

class UserAdmin(BaseUserAdmin):
    add_form = CustomUserCreationForm
    # 配置新增用户的字段集,确保permissions字段可见
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', 'password1', 'password2', 'permissions'),
        }),
    )

# 替换默认的UserAdmin注册
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

额外说明

  • 如果你的权限还关联其他模型,可以叠加prefetch_related处理多对多/反向关联的预取需求。
  • 该方案无需依赖get_queryset方法,直接在表单层面修改权限的查询集,完美适配新增用户的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:00:55