2014-01-25 68 views
0

不知道我是否應該將其分成單獨的帖子,我必須基本上覆制粘貼每個問題的整個代碼。我希望這很好。Django模型與額外的領域,許多tomanyfield每個對象的權限 - 我做對了嗎?

  1. 我有我的應用程序中的渠道。每個用戶可以對每個頻道具有不同的訪問級別。我需要能夠查詢用戶可以閱讀的每個頻道的條目。我已經將它實現爲ManyToManyField,是否有更好的解決方案?

  2. 在我的許可模式中,我有ForeignKey(User, blank=True, null=True)unique_together = ("channel", "user")。我使用帶有空用戶字段的權限對象來存儲未指定用戶的默認訪問級別。這會使我陷入麻煩嗎? (null!= null on database level)

  3. 我想在ChannelCreateForm中設置默認訪問級別,所以我添加了額外的字段並覆蓋了相關視圖的form_valid方法。有沒有更適當的方法來做到這一點?

  4. 我有點兒在這裏即興創作。請指出您在我的代碼中找到的任何醜陋。那就是:

    class Channel(models.Model):  
        name = models.CharField(max_length=30, unique=True) 
        title = models.CharField(max_length=70, blank=True, null=True) 
        description = models.TextField(blank=True, null=True)  
        owner = models.ForeignKey(User) 
        permission = models.ManyToManyField(User, through='ChannelPermission', related_name="permission")    
    
    
    class ChannelPermission(models.Model): 
        PERM_CHOICES = (
          (0, 'none'), 
          (1, 'read'), 
          (2, 'post'),         
          (3, 'edit'), 
          (4, 'lock'), 
          (5, 'manage'), 
         ) 
        channel = models.ForeignKey(Channel) 
        user = models.ForeignKey(User, blank=True, null=True) 
        access = models.IntegerField(choices=PERM_CHOICES, default=0) 
    
        class Meta: 
         unique_together = ("channel", "user") 
    
    
    class ChannelCreateForm(forms.ModelForm): 
        access = forms.ChoiceField(label = 'Default access', 
               choices = (
                (0, 'none'), 
                (1, 'read'), 
                (2, 'post'),         
                (3, 'edit'),         
               ) 
        ) 
    
        class Meta: 
         model = Channel 
         fields = ['name', 'title', 'access', 'description'] 
    
    
    class ChannelCreate(CreateView): 
        form_class = ChannelCreateForm 
        template_name = 'index_form.html' 
    
        def form_valid(self, form): 
         obj = form.save(commit=False) 
         obj.owner = self.request.user 
         obj.save() 
         perm = ChannelPermission(user=None, channel=obj, access=form.cleaned_data['access']) 
         perm.save() 
         return HttpResponseRedirect(reverse('some_name')) 
    

回答

0
  1. 是的,我想這個做同樣的方式。
  2. 我可能會改變0,1,2等鍵到短字符串只是爲了確保0 從來沒有使任何麻煩。另外,最好在數據庫中有意義的記錄,而不是0,1,2等,default='none'看起來會更好。除此之外,這聽起來很好。
  3. 也許更好的解決辦法是不能在視圖中製作它。 Channel模型的save方法中,我會做ChannelPermission的創建。另外,可能最好的想法是將默認ChannelPermission創建的邏輯移動到模型管理器中。
  4. 怎麼樣

    class Channel(models.Model): 
        name = models.CharField(max_length=30, unique=True) 
        title = models.CharField(max_length=70, blank=True, null=True) 
        description = models.TextField(blank=True, null=True) 
        owner = models.ForeignKey(User) 
        permission = models.ManyToManyField(User, through='ChannelPermission', related_name="permission") 
    
    
    class ChannelPermission(models.Model): 
        PERM_CHOICES = (
          ('none', 'None'), 
          ('read', 'Read Only'), 
          ('post', 'Post'), 
          ('edit', 'Edit'), 
          ('lock', 'Lock'), 
          ('manage', 'Manage'), 
         ) 
        channel = models.ForeignKey(Channel) 
        user = models.ForeignKey(User, blank=True, null=True) 
        access = models.IntegerField(choices=PERM_CHOICES, default='none') 
    
        class Meta: 
         unique_together = ("channel", "user") 
    
    
    class ChannelCreateForm(forms.ModelForm): 
        access = forms.ChoiceField(label = 'Default access', 
               choices = (
                ('none', 'None'), 
                ('read', 'Read Only'), 
                ('post', 'Post'), 
                ('edit', 'Edit'), 
    
               ) 
        ) 
    
        class Meta: 
         model = Channel 
         fields = ['name', 'title', 'access', 'description'] 
    
        def save(self, commit=True): 
         instance = super(ChannelCreateForm, self).save(commit) 
         perm = ChannelPermission(user=None, channel=self.instance, access=self.cleaned_data['access']) 
         perm.save() 
         return instance 
    
    
    class ChannelCreate(CreateView): 
        form_class = ChannelCreateForm 
        template_name = 'index_form.html' 
    
        def form_valid(self, form): 
         self.object = form.save(commit=False) 
         self.object.owner = self.request.user 
         self.object.save() 
         return super(ModelFormMixin, self).form_valid(form) 
    
+0

2.我主要是擔心unique_together 「不工作」 空值。你說模型,但你的代碼說的形式。 ;]是的,將它放在表單代碼中更有意義。謝謝。 – petr0

+0

在這種情況下,您應該從ChannelPermission中爲用戶刪除null = True,blank = True,並在Channel模型中創建另一個名爲default_permission的字段 –

相關問題