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

Django Admin中按用户类型配置模型字段编辑权限的方案咨询

Django Admin 字段级权限控制方案

针对不同用户类型在Admin中只能编辑指定字段的需求,这里有几个实用的实现方案:

方法1:重写ModelAdmin的只读字段方法

直接利用Django Admin内置能力,根据当前用户类型动态设置可编辑字段,无需额外依赖。

示例代码:

from django.contrib import admin
from .models import ModelFamily, UserTotal, UserParcial, UserBase

class ModelFamilyAdmin(admin.ModelAdmin):
    # 列表页显示所有字段
    list_display = [field.name for field in ModelFamily._meta.fields]

    def get_readonly_fields(self, request, obj=None):
        user = request.user
        # 按用户类型定义可编辑字段范围
        if isinstance(user, UserBase):
            editable_fields = ['field1', 'field2']
        elif isinstance(user, UserParcial):
            editable_fields = ['field1', 'field2', 'field3', 'field4', 'field5']
        elif isinstance(user, UserTotal):
            editable_fields = [field.name for field in ModelFamily._meta.fields]
        else:
            editable_fields = []
        
        # 计算只读字段:所有字段减去可编辑字段
        all_fields = [field.name for field in ModelFamily._meta.fields]
        return [f for f in all_fields if f not in editable_fields]

admin.site.register(ModelFamily, ModelFamilyAdmin)

如果需要更精准控制表单显示的字段组,还可以重写get_fieldsets方法,只渲染用户有权编辑的字段集合。

方法2:自定义ModelForm禁用字段

通过自定义表单,初始化时根据用户类型直接禁用无权限的字段(页面上无法输入,比只读字段的限制更严格)。

示例代码:

from django import forms
from django.contrib import admin
from .models import ModelFamily, UserTotal, UserParcial, UserBase

class ModelFamilyForm(forms.ModelForm):
    class Meta:
        model = ModelFamily
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        # 取出传递进来的当前用户
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)
        
        if user:
            if isinstance(user, UserBase):
                # 仅保留field1、field2可编辑,其余字段禁用
                for field_name in self.fields:
                    if field_name not in ['field1', 'field2']:
                        self.fields[field_name].disabled = True
            elif isinstance(user, UserParcial):
                disabled_fields = [f for f in self.fields if f not in ['field1','field2','field3','field4','field5']]
                for field_name in disabled_fields:
                    self.fields[field_name].disabled = True

class ModelFamilyAdmin(admin.ModelAdmin):
    form = ModelFamilyForm

    def get_form(self, request, obj=None, **kwargs):
        # 将当前用户传递给自定义表单
        kwargs['user'] = request.user
        return super().get_form(request, obj, **kwargs)

admin.site.register(ModelFamily, ModelFamilyAdmin)

方法3:自定义字段级权限+用户组管理

如果需要后期灵活配置权限(比如通过Admin界面调整),可以为每个字段创建自定义权限,再分配给对应用户组。

步骤1:为模型添加字段级权限

class ModelFamily(models.Model):
    field1 = models.IntegerField()
    field2 = models.CharField(max_length=100)
    # 其余8个字段...

    class Meta:
        permissions = [
            ('can_edit_field1', 'Can edit field1'),
            ('can_edit_field2', 'Can edit field2'),
            # 为每个字段添加对应的编辑权限
        ]

执行python manage.py makemigrations和migrate,将权限同步到数据库。

步骤2:在Admin中检查权限

from django.contrib import admin
from .models import ModelFamily

class ModelFamilyAdmin(admin.ModelAdmin):
    list_display = [field.name for field in ModelFamily._meta.fields]

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = []
        all_fields = [field.name for field in ModelFamily._meta.fields]
        # 检查用户是否拥有对应字段的编辑权限
        for field in all_fields:
            if not request.user.has_perm(f'你的应用名.can_edit_{field}'):
                readonly_fields.append(field)
        return readonly_fields

admin.site.register(ModelFamily, ModelFamilyAdmin)

之后你可以在Django Admin的用户组管理界面,把对应字段权限分配给UserTotal、UserParcial、UserBase组即可。

内容的提问来源于stack exchange,提问作者Juan Manuel Amato

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:40:57