[英]Django modelform with extra field, permissions per object as manytomanyfield - am I doing it right?
不知道是否应该将其拆分为单独的帖子,我基本上必须将每个问题复制并粘贴整个代码。 我希望这很好。
我的应用程序中有频道。 每个用户可以对每个通道具有不同的访问级别。 我需要能够查询每个用户可以阅读的条目。 我已将其实现为ManyToManyField,是否有更好的解决方案?
在我的权限模型中,我具有ForeignKey(User, blank=True, null=True)
和unique_together = ("channel", "user")
。 我使用具有空用户字段的权限对象来存储未指定用户的默认访问级别。 这会给我带来麻烦吗? (null!=在数据库级别为null)
我想在ChannelCreateForm中设置默认访问级别,所以我向它添加了额外的字段并覆盖了相关视图的form_valid方法。 有没有更合适的方法可以做到这一点?
我在这里即兴创作。 请指出您在我的代码中发现的任何丑陋之处。 这里是:
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'))
default='none'
看起来会更好。 除此之外,这听起来还不错。 Channel
模型的save
方法中创建ChannelPermission
。 同样,可能的好主意是将默认ChannelPermission
创建的逻辑移到模型管理器中。 那个怎么样
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.