简体   繁体   English

为超级用户以外的用户排除 Django admin 中的字段

[英]Exclude fields in Django admin for users other than superuser

I have a simple MyUser class with PermissionsMixin .我有一个带有PermissionsMixin的简单MyUser类。 user.is_superuser equals True only for superusers. user.is_superuser仅对于超级用户才等于True I'd like to be able to do something similar to this in my admin.py :我希望能够在我的admin.py做类似的admin.py

    if request.user.is_superuser:
        fieldsets = (
            (None, {'fields': ('email', 'password')}),
            ('Permissions', {'fields': ('is_admin','is_staff')}),
            ('Place', {'fields': ('place',)}),
            ('Important dates', {'fields': ('last_login',)}),
        )
    else:
        fieldsets = (
            (None, {'fields': ('email', 'password')}),
            #('Permissions', {'fields': ('is_admin','is_staff')}),
            ('Place', {'fields': ('place',)}),
            ('Important dates', {'fields': ('last_login',)}),
        )

Basically I want my users to be able to create other users, but not give them admin or stuff permissions.基本上我希望我的用户能够创建其他用户,但不给他们管理员或东西权限。 Only superusers should be able to do that.只有超级用户才能做到这一点。

Accepted answer is close but as others point out, get_form is called multiple times on the same instance of the Admin model and the instance is reused, so you can end up with fields repeated or other users seeing the fields after self.fields is modified.接受的答案很接近,但正如其他人指出的那样,在 Admin 模型的同一实例上多次调用 get_form 并且该实例被重用,因此您最终可能会重复字段或其他用户在修改 self.fields 后看到这些字段。 Try this out in Django <=1.6:在 Django <=1.6 中试试这个:

class MyAdmin(admin.ModelAdmin):

    normaluser_fields = ['field1','field2']
    superuser_fields = ['special_field1','special_field2']

    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            self.fields = self.normaluser_fields + self.superuser_fields
        else:
            self.fields = self.normaluser_fields

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

Looks like, Django 1.7 introduces a get_fields() method you can override which is a much nicer approach:看起来,Django 1.7 引入了一个 get_fields() 方法,您可以覆盖它,这是一个更好的方法:

https://github.com/django/django/blob/d450af8a2687ca2e90a8790eb567f9a25ebce85b/django/contrib/admin/options.py#L276 https://github.com/django/django/blob/d450af8a2687ca2e90a8790eb567f9a25ebce8​​5b/django/contrib/admin/options.py#L276

If I understand you correctly, what you want to do is override the get_form method for the ModelAdmin.如果我理解正确,您想要做的是覆盖 ModelAdmin 的 get_form 方法。 Base on the example from django documentation , it would look something like this:基于django 文档中的示例,它看起来像这样:

class MyUserAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        self.exclude = []
        if not request.user.is_superuser:
            self.exclude.append('Permissions') #here!
        return super(MyUserAdmin, self).get_form(request, obj, **kwargs)

Now you might need to hack around a little and maybe override the save method as well.现在您可能需要稍微修改一下,并且还可能覆盖 save 方法。 I did something similar not long ago, it's not so complicated (and the docs are fantastic).不久前我做了类似的事情,它并没有那么复杂(而且文档很棒)。

There might be a simpler solution but your question is kinda general and you didn't share your user model, so I can't tell you exactly how to work this out.可能有一个更简单的解决方案,但你的问题有点笼统,而且你没有分享你的用户模型,所以我不能确切地告诉你如何解决这个问题。 I hope this helps!我希望这会有所帮助!

Django now has a get_exclude method on ModelAdmin for excluding fields programmatically. Django 现在在get_exclude上有一个get_exclude方法,用于以编程方式排除字段。

It takes the current request and the object (if any) as argument.它将当前请求和对象(如果有)作为参数。 You can put a check there on the request argument to see if they're a superuser and check您可以在 request 参数上进行检查以查看他们是否是超级用户并检查

class MyModelAdmin(admin.ModelAdmin):
    def get_exclude(self, request, obj=None):
        excluded = super().get_exclude(request, obj) or [] # get overall excluded fields

        if not request.user.is_superuser: # if user is not a superuser
            return excluded + ['extra_field_to_exclude']

        return excluded # otherwise return the default excluded fields if any

According to Django Docs , the correct way is to create a ModelForm for superusers and another for normal users.根据Django Docs ,正确的方法是为超级用户创建一个 ModelForm ,为普通用户创建另一个。 Then you specify each form in the get_form method of your ModelAdmin:然后在 ModelAdmin 的 get_form 方法中指定每个表单:

class MyModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            kwargs['form'] = MySuperuserForm
        else:
            kwargs['form'] = MyNormalForm
        return super(MyModelAdmin, self).get_form(request, obj, **kwargs)

Starting Django 1.7 you can replace the base class of your model admin with something like:从 Django 1.7 开始,您可以使用以下内容替换模型管理员的基类:

class SuperuserAwareModelAdmin(admin.ModelAdmin):
    superuser_fields = None
    superuser_fieldsets = None

    def get_fieldsets(self, request, obj = None):
        if request.user.is_superuser and self.superuser_fieldsets:
            return (self.fieldsets or tuple()) + self.superuser_fieldsets
        return super(SuperuserAwareModelAdmin, self).get_fieldsets(request, obj)

    def get_fields(self, request, obj = None):
        if request.user.is_superuser and self.superuser_fields:
            return (self.fields or tuple()) + self.superuser_fields
        return super(SuperuserAwareModelAdmin, self).get_fields(request, obj)

Example:示例:

class MyModelAdmin(SuperuserAwareModelAdmin):
    superuser_fieldsets = (
        (_('Permissions'), {'fields': ('is_staff', )}),
    )

The SuperuserAwareModelAdmin base class can also be created as a mixin. SuperuserAwareModelAdmin基类也可以创建为 mixin。

I solved it this way inspired by previous answers.我受先前答案的启发以这种方式解决了这个问题。 In my example only a superuser may create a superuser.在我的示例中,只有超级用户可以创建超级用户。 If it is not superuser the checkbox in the form is missing.如果不是超级用户,则缺少表单中的复选框。 It works for me and I hope it is correct:它对我有用,我希望它是正确的:

    def get_form(self, form_class=form_class):

        if self.request.user.is_superuser is False:
            self.form_class.base_fields.pop('is_superuser')
        return super(AccountCreateView, self).get_form()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Django-管理界面-允许为非超级用户创建用户 - Django - Admin Interfaces - to allow create users for non-superuser Django 1.8:具有超级用户管理功能的自定义“其他字段很少的用户”身份验证 - Django 1.8 : Customized 'User with few other fields' authentication with superuser management Django 无法在“默认”以外的其他数据库中创建超级用户 - Django fails to create superuser in other db than 'default' Django 管理员:在列表中排除字段但不在编辑中 - Django admin: Exclude fields in listing but not in editing Django 管理应用程序对超级用户 100% 有效,但对于具有完全权限的员工用户,某些应用程序不会为用户显示 - Django admin application works 100% for superuser but for staff users with full permissions some apps don't appear for users django:管理员通知,如果超级用户显示 - django: admin notifications,display if superuser Django 管理员登录不适用于超级用户 - Django admin login not working for superuser Django-使管理员字段对某些用户不可见 - Django - make admin fields invisible to some users Django-从LDAP身份验证中排除超级用户 - Django - Exclude superuser from LDAP auth 提供取决于Django Admin中其他字段的选择 - Offering choices that depend on other fields in Django Admin
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM