了解Python类或自定义Django UserAdmin模型

时间:2010-12-01 03:43:17

标签: python django-models django-admin

我试图覆盖Django UserAdmin模型的一些行为。特别是,我想隐藏非超级用户的“超级用户”字段。

所以,我的方法是:

class ModelAdmin(BaseModelAdmin):
    "Encapsulates all admin options and functionality for a given model."

    # ...

    def has_change_permission(self, request, obj=None):
        """
        Returns True if the given request has permission to change the given
        Django model instance.

        If `obj` is None, this should return True if the given request has
        permission to change *any* object of the given type.
        """
        opts = self.opts
        return request.user.has_perm(opts.app_label + '.' + opts.get_change_permission())

    #...

基于我在ModelAdmin中找到的内容

class UserAdmin(UserAdmin):
    """
    ... my customised UserAdmin
    """

    # adding a new method
    def is_superuser(self, request):
        "Returns True if the given user is a superuser."
        return request.user.is_superuser

    # then elsewhere 'hopefully' show a slightly different fieldset
    # the following, of course, doesn't work.

    fieldsets = (
        (None, {
            'fields': (
                ("first_name", "last_name"), 
                ("email", "password"), 
                "is_staff", 
                "is_active", 
                "is_superuser" if self.is_superuser() else None

            )   
        }),
        ('Groups', {
            'fields': (
                'groups', 
            )
        }),
        ('Meta', {
            'classes': ('collapse',),
            'fields': (
                'username',
                "last_login", 
                "date_joined"
            )
        })
    )

所以,我的问题是:

  • 如何在我的新自定义UserAdmin类中创建def,如上所述,以及如何调用它? (我怎么知道我在适当的背景下这样做)
  • 第2部分(奖金):我如何简洁地在表单中包含/排除'is_superuser'字段,正如上面的伪代码所暗示的那样?

亲切的感谢老乡!

~Daryl

谢谢

2 个答案:

答案 0 :(得分:1)

如果您只是想禁止用户向超级用户宣传自己,请覆盖YourUserAdmin.get_readonly_fields():

class YourUserAdmin(admin.ModelAdmin):
    ...
    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return None
        try:
            return self.readonly_fields + ('is_superuser',)
        except:
            return ('is_superuser',)

您必须取消注册默认的User / UserAdmin,然后注册您自己的。

admin.site.unregister(User)
admin.site.register(User, YourUserAdmin)

然而,管理员的Z​​EN说:

  

在它的核心,Django的管理员专为单一活动而设计:可信用户编辑结构化内容。

如果用户不受信任,请不要授予他编辑用户帐户的编辑权限。即使您隐藏了superadmin选项和“按superadmin状态过滤”过滤器,他也可以更改您的密码并以您的身份登录。因此,如果您需要一些不受信任的用户来编辑用户帐户,请忘记管理员并编写您自己的dumbed down界面。

答案 1 :(得分:0)

没有使用Django的经验,但在这种情况下考虑关闭可能会有所帮助:

class UserAdmin(UserAdmin):

    # adding a new method
    def is_superuser(self, request):
        "Returns True if the given user is a superuser."
        return request.user.is_superuser

    def gen_fieldset(self, request):
        '''
        If request.user.is_supeuser == true then return fieldset generator for superuser.
         Else return fieldset generator for normal user.
         ''' 
        su = is_superuser(request)
        def get_fieldset():
            if su:
                return super_user_fieldset
            else:
                return normal_user_fieldset
        return get_fieldset

用法如下:

obj = UserAdmin()
request = ... #Generate a normal or super-user request.
fieldset = obj.gen_fieldset(request)
# Sometime later when you want to use the fieldset...
fields = fieldset() # Function will decide which fieldset to give based on gen_fieldset() call earlier.

所以基本的想法是你可以提前配置 get_fieldset()(通过调用 gen_fieldset(),在这里使用闭包)返回相应的用户级别的fieldset。为用户提供 gen_fieldset()返回的函数对象,只要用户调用它,它就会在以后生成相应的字段集。

注意:如果您在我建议Google搜索其他示例并使用方案之前从未使用过闭包。可能还有其他解决方案可以更好地适应您的情况(同样,不熟悉Django),但这是我想到的第一件事。