Django Admin readonly_fields:为什么两个不同的用户看到相同的字段?

问题描述 投票:0回答:2

我创建了一些代码来区分 Django admin 中的两个用户组,从而导致显示所有字段为只读或仅显示其中的某些字段,这些字段直接在 ModelAdmin 类中设置。

首先这是代码:

class PersonAdmin(admin.ModelAdmin):
    readonly_fields = ('created_at','created_by',)

def get_form(self, request, obj=None, **kwargs):
    if obj:     # we are in edit mode
        if request.user.is_superuser:
            self.readonly_fields = ()
        else:
            for group in request.user.groups.all():
                if str(group) == 'readonlyuser':
                    allfields = tuple(obj._meta.get_all_field_names())
                    self.readonly_fields = allfields

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

我在各组之间进行划分并相应地设置字段。如果两个组的用户不同时登录,则一切正常! “只读”用户登录后,管理员用户也将获得所有字段只读。

我的检查也提供了解决方案: 如果我在 for 块中为管理员用户添加一个额外的 if 语句,一切都会按预期工作。

if str(group) == 'adminuser':
    self.readonly_fields = PersonAdmin.readonly_fields

为什么会这样以及那里发生了什么?

我没有进行特殊的缓存设置,它发生在开发服务器以及带有 WSGI 的 Apache 上。

根据我的理解 request.user.groups.all() 应该返回 当前登录用户所属的所有组。如果不同 IP 和会话上的另一个用户与此 if 块匹配,Django 从哪里获取所有字段(只读)?

python django django-admin
2个回答
16
投票

ModelAdmin 仅针对其收到的所有请求实例化一次。因此,当您像这样定义只读字段时,您就将其永久设置。

只要您运行 Django 1.2+,就可以使用一个

get_readonly_fields
方法来实现此目的:

class MyModelAdmin(admin.ModelAdmin):
    ...

    def get_readonly_fields(self, request, obj=None):
        if request.user.is_superuser:
            return super(MyModelAdmin, self).get_readonly_fields(request, obj)
        else:
            return ('created_at', 'created_by')

readonly_fields
中删除
ModelAdmin
属性,或将其设置为对 everyone 只读的字段。然后,在
else
块中指定仅对非超级用户只读的所有字段。


1
投票

因为 Django Admin 中的字段在 Web 服务器重新启动时第一次运行后被设置(即缓存)。您可能可以通过重新声明 readonly_fields 元组来解决它。像这样的东西(未经测试):

def get_form(self, request, obj=None, **kwargs):  
    self.readonly_fields = ('created_at','created_by',)
    # ...
© www.soinside.com 2019 - 2024. All rights reserved.