2012-07-19 258 views
2

我想限制組中的用戶無法更改字段,他們的組無權更改。例如:限制Django管理員更改權限

class StudentReferral(models.Model): 
    teacher = models.CharField(max_length=50) 
    referral_first_name = models.CharField(max_length=50) 
    referral_last_name = models.CharField(max_length=50) 
    accepted = models.BooleanField(blank=True) 

現在老師都在一個用戶組,誰接受或拒絕轉診的人在另一個用戶組。教師用戶組只能編輯以下字段:teacher,referral_first_name和referral_last_name。其他用戶組只能編輯已接受的字段。兩組都應該能夠看到所有的字段。

是否有東西內置到Django,使這種可能或一種自定義的方式做到這一點?

回答

5

覆蓋ModelAdmin.get_fieldsets,並做類似如下:

class MyModelAdmin(admin.ModelAdmin): 
    ... 
    fieldsets = (
     ... # Standard/all fields 
    ) 
    teacher_fieldsets = (
     ... # Only fields teachers can see 
    ) 

    def get_fieldsets(self, request, obj=None): 
     if request.user.groups.filter(name='Teachers').exists(): 
      return self.teacher_fieldsets 
     else: 
      return super(MyModelAdmin, self).get_fieldsets(request, obj=obj) 

編輯

對不起,我錯過了一些關於他們仍然應該能夠看到所有的領域,只是對其進行編輯。我已經保留原始答案,因爲它可能對你仍然有用。對於這一點,不過,你需要重寫ModelAdmin.get_readonly_fields

class MyModelAdmin(admin.ModelAdmin): 
    ... 
    readonly_fields = ('teacher', 'referral_first_name', 'referral_last_name') 
    teacher_readonly_fields = ('accepted',) 

    def get_readonly_fields(self, request, obj=None): 
     if request.user.groups.filter(name='Teachers').exists(): 
      return self.teacher_readonly_fields 
     else: 
      return super(MyModelAdmin, self).get_readonly_fields(request, obj=obj) 

我假設這裏的選擇是唯一的老師或「其他用戶」。如果還有其他類型需要考慮,或者您不希望某些情況下字段受限制,則可能需要刪除readonly_fields屬性並將其替換爲other_readonly_fields之類的內容,然後相應地進行分支(readonly_fields的默認值僅爲字段在模型上有editable=False)。

另外,請注意,如果某個字段是必需的,那麼您也無法使其成爲只讀字段。如果其中一些是必填字段,那麼您還需要覆蓋ModelForm.__init__,以便在需要一些額外的hackery的情況下不需要它們(ModelForm無權訪問request,通常):

class MyModelForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 

    def __init__(self, *args, **kwargs): 
     self.request = kwargs.pop('request') 
     super(MyModelForm, self).__init__(*args, **kwargs) 

     if self.request is not None: 
      if self.request.user.groups.filter(name='Teachers').exists(): 
       self.fields['accepted'].required = False 

class MyModelAdmin(admin.ModelAdmin): 
    form = MyModelForm 
    ... 
    def get_form(self, request, obj=None, **kwargs): 
     ModelForm = super(MyModelAdmin, self).get_form(request, obj=obj, **kwargs) 
     class WrapperModelForm(ModelForm): 
      def __new__(cls, *args, **kwargs): 
       kwargs['request'] = request 
       return ModelForm(*args, **kwargs) 
     return WrapperModelForm 
+0

第二種方法奏效了。謝謝 – CF711 2012-07-24 20:05:43