我有一个简单的MyUser
类,PermissionsMixin
. user.is_superuser
等于仅对超级用户True
。我希望能够在我的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',)}),
)
基本上,我希望我的用户能够创建其他用户,但不授予他们管理员或东西权限。只有超级用户才能做到这一点。
接受的答案很接近,但正如其他人指出的那样,get_form在 Admin 模型的同一实例上被多次调用,并且该实例被重用,因此您最终可能会重复字段或其他用户在修改 self.fields 后看到字段。在 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)
看起来,Django 1.7 引入了一个可以覆盖的 get_fields() 方法,这是一种更好的方法:
https://github.com/django/django/blob/d450af8a2687ca2e90a8790eb567f9a25ebce85b/django/contrib/admin/options.py#L276
如果我理解正确,您要做的是覆盖模型管理员的get_form方法。基于 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)
现在您可能需要稍微修改一下,也许还需要覆盖保存方法。不久前我做了类似的事情,它并不那么复杂(而且文档很棒)。
可能有一个更简单的解决方案,但你的问题有点笼统,你没有分享你的用户模型,所以我不能确切地告诉你如何解决这个问题。我希望这有帮助!
Django 现在在 ModelAdmin 上有一个get_exclude
方法,用于以编程方式排除字段。
它将当前请求和对象(如果有)作为参数。您可以在请求参数上进行检查,以查看他们是否是超级用户并检查
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
根据Django Docs的说法,正确的方法是为超级用户创建一个ModelForm,为普通用户创建一个ModelForm。然后,在模型管理员的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)
从 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)
例:
class MyModelAdmin(SuperuserAwareModelAdmin):
superuser_fieldsets = (
(_('Permissions'), {'fields': ('is_staff', )}),
)
SuperuserAwareModelAdmin
基类也可以创建为mixin。
我以这种方式解决了它,灵感来自以前的答案。在我的示例中,只有超级用户可以创建超级用户。如果不是超级用户,则表单中的复选框将丢失。它对我有用,我希望它是正确的:
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()