簡體   English   中英

了解django admin readonly_fields

[英]Understanding django admin readonly_fields

我創建了一些代碼來區分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)

我在組之間划分並相應地設置字段。 如果來自兩個組的用戶沒有同時登錄,一切正常! 在“只讀”用戶登錄后,adminuser也將只讀取所有字段。

我的檢查也提供了一個解決方案:如果我在for block中為adminuser添加了一個額外的if語句,一切都按預期工作。

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

為什么那樣以及那里發生了什么?

我沒有進行特殊的緩存設置,它發生在開發服務器以及帶有WSGI的Apache上。

根據我的理解,request.user.groups.all()應該返回當前登錄用戶所屬的所有組。 如果另一個用戶在不同的IP和會話上匹配這個if塊,那么Django從哪里獲取allfields(readonly)?

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')

ModelAdmin刪除readonly_fields屬性,或將其設置為每個人應該只讀的字段。 然后,在else塊中指定僅對非超級用戶應該只讀的所有字段。

因為Django Admin中的字段在重新啟動Web服務器后第一次運行后被設置(即緩存)。 你可以通過重新聲明readonly_fields元組來繞過它。 像這樣(未經測試):

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