根据用户组更改Django管理后台筛选列表字段

0 投票
3 回答
960 浏览
提问于 2025-04-17 07:58

我正在使用Django的管理后台来生成一个表单,以便将一些数据存入数据库,但我需要根据用户组来隐藏某些表单字段。

假设我有一个模型,像这样:

class Product(models.Model):
    name = models.CharField(...)
    description = models.CharField(...)
    approved = models.CharField(max_length=1, choices=(('y', 'yes'), ('n','no'), ('w', 'waiting'))

我希望“基本”组的用户在表单中只看到“姓名”和“描述”,而“高级”组的用户则可以看到“批准”状态。

我需要使用自定义模板吗?无论你回答是还是不是,请帮我提供一些文档或示例。

谢谢。

3 个回答

0

如果你想只隐藏某些特定的字段,同时又允许进行修改,最简单的办法可能是把你的管理员用户放到一个新的组里,然后根据这个组的成员身份来减少可见的字段。下面是一个可以直接使用的类:

class ExternalAdminModelAdmin(admin.ModelAdmin):
    external_admin_group = 'external_admin'
    hidden_fields = []

    def get_form(self, request, obj=None, **kwargs):
        self.fields = [field.name for field in Node._meta.local_concrete_fields if not field.name == 'id']

        if Group.objects.get(name=self.external_admin_group).user_set.filter(id=request.user.id).exists():
            for field_name in self.hidden_fields:
                self.fields.remove(field_name)

        return super(ExternalAdminModelAdmin, self).get_form(request, obj, **kwargs)

你只需要为你的模型设置隐藏字段的属性就可以了:

@admin.register(MyModel)
class MyAdmin(ExternalAdminModelAdmin):
    hidden_fields = ['sensitive_field']
1

你可以在你的表单里提供一个 __init__ 方法。在这个方法里,如果有用户对象的话,你就可以访问到它。根据用户的团队成员身份,你可以对表单进行定制。

一些代码片段:

函数的签名和获取用户对象:

 def __init__(self,*args, **kwargs):       
        self.user=None
        if kwargs:
            self.user = kwargs.pop('user')

检查用户是否在某个组里的函数:

def is_user_in_group(user,group_name):
    return user.groups.filter(name=group_name).count() == 1

让某个字段隐藏的代码片段——这段代码会放在你的 __init__ 方法里:

self.fields['some_field_to_hide'].widget = widgets.HiddenInput

我这里是凭记忆说的,所以请原谅我可能的拼写错误。

2

你可以在ProductAdmin类中重写get_form这个方法。原来的方法是这样的:

def get_form(self, request, obj=None, **kwargs):
    ....
    ....
    defaults = {
        "form": self.form,
        "fields": fields,
        "exclude": exclude,
        "formfield_callback": curry(self.formfield_for_dbfield, request=request),
    }
    defaults.update(kwargs)
    ...

这样你就可以动态地改变self.form、fields或者exclude这几个内容了。

撰写回答