简体   繁体   English

了解django admin readonly_fields

[英]Understanding django admin readonly_fields

I created some code to differentiate between two usergroups in Django admin, resulting in showing all fields readonly or only some of them, which are set directly in the ModelAdmin class. 我创建了一些代码来区分Django admin中的两个用户组,导致只读取所有字段或仅显示其中的一些字段,这些字段直接在ModelAdmin类中设置。

At first here is the code: 这里首先是代码:

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)

I divide between the groups and set the fields accordingly. 我在组之间划分并相应地设置字段。 Everything works fine if users from the two groups are not logged in at the same time! 如果来自两个组的用户没有同时登录,一切正常! After a 'readonly' user logged in, the adminuser will get all fields readonly too. 在“只读”用户登录后,adminuser也将只读取所有字段。

My inspections provided a solution also: If I put an additional if statement for the adminuser within the for block everything works as expected. 我的检查也提供了一个解决方案:如果我在for block中为adminuser添加了一个额外的if语句,一切都按预期工作。

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

Why is that and what's happening there? 为什么那样以及那里发生了什么?

I have no special cache settings made and it happens on the dev server as well as on an Apache with WSGI. 我没有进行特殊的缓存设置,它发生在开发服务器以及带有WSGI的Apache上。

From my understanding request.user.groups.all() should return all groups the currently logged in user belongs to. 根据我的理解,request.user.groups.all()应该返回当前登录用户所属的所有组。 Where does Django get the allfields (readonly) from, if another user on a different IP and session match this if block? 如果另一个用户在不同的IP和会话上匹配这个if块,那么Django从哪里获取allfields(readonly)?

The ModelAdmin is only instantiated once for all requests that it receives. ModelAdmin仅对其收到的所有请求实例化一次。 So when you define the readonly fields like that, you're setting it across the board permanently. 因此,当您定义这样的只读字段时,您将永久地设置它。

As long as you're running Django 1.2+, there's a get_readonly_fields method you can use instead for exactly this purpose: 只要您运行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')

Remove the readonly_fields attribute from your ModelAdmin or set it to the fields that should be readonly for everyone . ModelAdmin删除readonly_fields属性,或将其设置为每个人应该只读的字段。 Then, in the else block specify all the fields that should be readonly only for non-superusers. 然后,在else块中指定仅对非超级用户应该只读的所有字段。

Because the fields in Django Admin are being set (ie cached) after being run the first time when the webserver was restarted. 因为Django Admin中的字段在重新启动Web服务器后第一次运行后被设置(即缓存)。 You could probably get around it by re-declaring the readonly_fields tuple. 你可以通过重新声明readonly_fields元组来绕过它。 Something like this (untested): 像这样(未经测试):

def get_form(self, request, obj=None, **kwargs):  
    self.readonly_fields = ('created_at','created_by',)
    # ...

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM