2012-01-24 88 views
1

我有一個修改的管理形式,其中我添加了一個字段,應該修改當前模型的父對象的值。現在,根據不同的用戶,我需要django的動態操作管理形式

  • 改變,額外的場
  • 設置另一個字段爲只讀的查詢集(或更好,甚至完全隱藏)

基本上我下面的代碼按我的預期工作。超級用戶獲取整個查詢集,另一個字段是而不是只讀。所有其他用戶都獲得有限的查詢集,而其他字段只讀。但是,一旦我在另一個瀏覽器中打開該網站並且以非超級用戶身份打開該網站,即使超級用戶也可以獲得與非超級用戶相同的結果。似乎django以某種方式緩存結果?如果我在條件分支中放置一些打印語句,它們會被正確打印。所以這個方法每次都會被調用,似乎仍然會執行這些步驟。只有錯誤的結果。

這是一個緩存問題嗎?我在做什麼完全錯誤的事情?它可能是django測試服務器中的錯誤嗎?

def get_form(self, request, obj=None, **kwargs): 
    form = super(MultishopProductAdmin, self).get_form(request, obj, **kwargs) 
    if obj is not None: 
     form.declared_fields['categories'].initial = obj.product.category.all() 
    if not request.user.is_superuser: 
     user_site = request.user.get_profile().site 
     form.declared_fields['categories'].queryset = Category.objects.filter(site__id=user_site.id) 
     self.readonly_fields = ('virtual_sites',) 
     if obj is not None: 
      form.declared_fields['categories'].initial = obj.product.category.filter(site__id=user_site.id) 
    return form 

回答

0

所以我找不到一個真正聰明的方法來做我想用django管理員的自定義方法。我現在最終做的是實現管理員的change_view,手動設置我自己的窗體並從那裏執行所有我的自定義初始化。

然後,我通過設置change_form_template提供了一個自定義模板,該模板只是擴展了admin/change_form.html,但呈現了我自己的窗體而不是默認窗體。我還設置了extra_context['adminform'] = None,以便刪除默認的管理員表單。

這樣我現在就可以按我需要的方式定製我的表單,但仍然可以使用所有其他管理員的便利。到目前爲止,它似乎很好地工作。不是我認爲的最優雅的解決方案,而是我能想到的最好的解決方案。

1

是的,你做錯了。在Django 1.2+中,您可以使用get_readonly_fields

this answer

的的ModelAdmin只爲它接收的所有請求實例化一次。所以當你定義這樣的只讀字段時,你會永久性地在整個板上設置它。

關於改變queryset。從文檔:

class MyModelAdmin(admin.ModelAdmin): 
    def queryset(self, request): 
     qs = super(MyModelAdmin, self).queryset(request) 
     if request.user.is_superuser: 
      return qs 
     return qs.filter(author=request.user) 
+0

謝謝,那已經解決了我的只讀字段問題。然而'queryset'方法並不是我正在尋找的。我通常在categories屬性上使用'formfield_for_manytomany'。因爲這不是模型的一部分,所以'formfield_for_manytomany'不會被調用。任何其他方法,我可以限制它的查詢集呢? – Dennis

+0

當然,也傳遞它的初始數據。我實際上期望這很簡單,但除了通常的初始=參數之外,我找不到任何其他東西,但這並不足以滿足我的需求。 – Dennis

+0

你想過濾什麼?爲什麼? –

1

要擴大丹klasson的前面回答:在任意的ModelAdmin方法永遠不要設置實例屬性(如self.readonly_fields),以防止像你描述的一個問題。只能使用Django ModelAdmin的選項(這是類級別)或方法來操縱任何行爲。關於只讀字段,您可以使用具有以下簽名的ModelAdmin.get_readonly_fields方法:get_readonly_fields(self, request, obj=None)