2014-10-30 106 views
2

請幫幫我。我被困在我的django項目的一個地方,以便由老師生成問卷。我已經實現了我自己的UserAdmin模型,儘管is_staff,is_superuser字段,我有自己的布爾字段「is_teacher」。創建新用戶時,如果勾選「is_teacher」框,我想給該用戶權限來管理整個問卷模型,但刪除管理MyUser模型(創建,更改和刪除用戶)的權限Django Admin,自定義權限複選框

這就是我所有的' VE實現:

在models.py

class MyUserManager(BaseUserManager): 
    def create_user(self, username, email=None, password=None): 
     if not username: 
      raise ValueError('The given username must be set') 
     email = MyUserManager.normalize_email(email) 
     user = self.model(username=username, email=email, is_staff=True, is_active=True, is_superuser=False, is_teacher=True) 

     user.set_password(password) 
     user.save(using=self._db) 
     return user 

    def create_superuser(self, username, email, password): 
     u = self.create_user(username, email, password) 
     u.is_staff = True 
     u.is_active = True 
     u.is_superuser = True 
     u.is_teacher = True 
     u.save(using=self._db) 
     return u 


class MyUser(AbstractBaseUser): 
    username = models.CharField(max_length=30, unique=True) 
    email = models.EmailField(blank=True) 
    is_active = models.BooleanField(default=True) 
    is_staff = models.BooleanField(default=True) 
    is_superuser = models.BooleanField(default=False) 
    is_teacher = models.BooleanField(default=True) 

    objects = MyUserManager() 

    USERNAME_FIELD = 'username' 
    REQUIRED_FIELDS = ['email'] 

    def get_full_name(self): 
     return self.username 

    def get_short_name(self): 
     return self.username 

    def __unicode__(self): 
     return self.username 

    def has_perm(self, perm, obj=None): 
     return True 

    def has_module_perms(self, module): 
     return True 

在admin.py

class UserCreationForm(forms.ModelForm): 
    """ 
    A form that creates a user, with no privileges, from the given username and 
    password. 
    """ 
    error_messages = { 
     'password_mismatch': "The two password fields didn't match.", 
    } 
    password1 = forms.CharField(label="Password", 
     widget=forms.PasswordInput) 
    password2 = forms.CharField(label="Password confirmation", 
     widget=forms.PasswordInput) 

    class Meta: 
     model = MyUser 
     fields = ("username",) 

    def clean_password2(self): 
     password1 = self.cleaned_data.get("password1") 
     password2 = self.cleaned_data.get("password2") 
     if password1 and password2 and password1 != password2: 
      raise forms.ValidationError(
       self.error_messages['password_mismatch'], 
       code='password_mismatch', 
      ) 
     return password2 

    def save(self, commit=True): 
     user = super(UserCreationForm, self).save(commit=False) 
     user.set_password(self.cleaned_data["password1"]) 
     if commit: 
      user.save() 
     return user 


class UserChangeForm(forms.ModelForm): 
    password = ReadOnlyPasswordHashField(label="Password") 

    class Meta: 
     model = MyUser 
     fields = ('username', 'password', 'email', 'is_active', 'is_staff', 'is_superuser', 'is_teacher') 

    def clean_password(self): 
     # Regardless of what the user provides, return the initial value. 
     # This is done here, rather than on the field, because the 
     # field does not have access to the initial value 
     return self.initial["password"] 


class MyUserAdmin(UserAdmin): 
    form = UserChangeForm 
    add_form = UserCreationForm 

    list_display = ('username', 'email', 'is_teacher') 
    list_filter = ('is_staff', 'is_superuser', 'is_active') 
    fieldsets = (
     (None, {'fields': ('username', 'password')}), 
     ('Personal info', {'fields': ('email',)}), 
     ('Permissions', {'fields': ('is_superuser', 'is_teacher',)}), 
    ) 

    add_fieldsets = (
     (None, { 
      'classes': ('wide',), 
      'fields': ('username', 'email', 'password1', 'password2')} 
     ), 
    ) 


    search_fields = ('username', 'email') 
    ordering = ('username',) 
    filter_horizontal =() 
+1

建議你創建你所需要的權限的「教師組,然後該組中添加任何用戶,只要其'is_teacher'字段被設置爲'True'https://docs.djangoproject.com/zh/dev/topics/auth/default/#groups – Anentropic 2014-10-30 12:26:41

+0

感謝您的建議,但我不能這樣做。它必須這樣做:超級用戶正在創建新帳戶,勾選「is_teacher」字段並且必須添加所有權限。我只是不知道該放置哪些權限以及如何對其進行編碼。 – Skiben 2014-10-30 13:33:42

+0

https://docs.djangoproject.com/en/dev/topics/auth/default/#topic-authorization – madzohan 2014-10-30 13:48:35

回答

1

有兩種方法可以做到這個。一種是手動添加權限。您應該在MyUserAdmin類中執行此操作,覆蓋默認的保存方法。事情是這樣的:

def save_model(self, request, obj, form, change): 
    # ADD THE PERMISSIONS HERE LIKE SO: 

    obj.save() 
    if obj.is_teacher: 
     # This is just an example of a permission you can add 
     obj.user_permissions.add('questionaires_questionire_change', '......') 
    else: 
     # Remove the permissions in case a user was demoted from teacher status 
     obj.user_permissions.remove('questionaires_questionire_change', '......') 

現在,這樣做的另一種方式,我認爲這是最好的(因爲它不依賴於節省了用戶的機型,並且可以在未來,而不需要做的改變通過所有用戶更新權限):

您可以在他們的ModelAdmins中爲您的問卷和其他需要的模型覆蓋has_change_permission,has_add_permission和has_delete_permission。這是您的問卷調查模式(只顯示變更許可在這裏)的例子:

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.has_change_permission

class QuestionnaireAdmin(admin.ModelAdmin): 
    def has_change_permission(self, request, obj=None): 
     if request.user.is_teacher: 
      return True 
     # If a user is not a teacher, let Django evaluate their specific permissions (a superusuer will always have permission if you do it this way) 
     return super(QuestionnaireAdmin, self).has_change_permission(request, obj=None) 
+1

非常感謝!它終於起作用了! – Skiben 2014-10-30 17:10:09