【问题标题】:Validate Uniqueness Fields in Django Class Based View在基于 Django 类的视图中验证唯一性字段
【发布时间】:2015-10-12 05:27:34
【问题描述】:

我需要排除表单中的“用户”字段,因为“用户”是将添加模型的登录用户。阅读所有 Django 表单文档并在此处参考答案Django's ModelForm unique_together validation

我的 django views.py 仍然报告错误,其中 'user' 是登录用户

Request Method: POST
Request URL:    http://localhost:8080/flavor/add_flavor/
Django Version: 1.8
Exception Type: KeyError
Exception Value: 'user'

谁能指出我代码中的错误?

models.py

class Flavor(models.Model):
    user = models.ForeignKey(UserProfile, related_name='flavors', verbose_name=_('user'))

    # Attributes
    name = models.CharField(max_length=100, verbose_name=_('name'), help_text=_('Enter the flavor name'))
    date_created = models.DateField(_("date created"), default=datetime.date.today)

    class Meta:
        verbose_name = _('Flavor')
        verbose_name_plural = _('Flavors')
        ordering = ('name', 'user')
        unique_together = ('user', 'name')

forms.py

class FlavorForm(forms.ModelForm):
    class Meta:
        model = Flavor
        # Never use exclude keyword which involves Massive Assignment Risk
        fields = ('name', 'date_created')

    def __init__(self, *args, **kwargs):
        # set the user as an attribute of the form which is more robust
        # Always pop user from kwargs before calling super()
        self.user = kwargs.pop('user')
        super(FlavorForm, self).__init__(*args, **kwargs)

    def clean(self):
        '''
        To verify the uniqueness by the unique_together fields
        '''
        cleaned_data = super(FlavorForm, self).clean()

        if Flavor.objects.filter(name=cleaned_data.get('name',''), user=self.user).exists():
            raise ValidationError(_('You have already added a flavor with this name'), code='invalid')

        # Always return cleaned data
        return cleaned_data

views.py

class FlavorCreateView(LoginRequiredMixin, CreateView):
    model = Flavor
    form_class = FlavorForm
    template_name = 'flavor/add_flavor.html'
    view_name = 'add_flavor'
    success_url = reverse_lazy(view_name)

    def get_form_kwargs(self):
        '''
        This injects form with keyword arguments.
        '''
        kwargs = super(FlavorCreateView, self).get_form_kwargs()
        #Update the kwargs with the user_id
        kwargs['user'] = self.request.user
        return kwargs


    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST)
        if form.is_valid():
            form.save()
            # process cleaned data
            return HttpResponseRedirect(success_url)

        return render(request, self.template_name, {'form': form})

【问题讨论】:

    标签: django


    【解决方案1】:

    您已仔细定义 get_form_kwargs 以提供用户 kwarg。但是由于某种原因,您已经覆盖了post;您的版本直接实例化表单,忽略辅助方法。

    很少有理由在 CBV 中覆盖 post,当然也不是您的情况。删除整个方法。

    (注意,这与检查唯一性无关。)

    【讨论】:

    • 您好丹尼尔,感谢您回答我的问题。 :) 我在这上面花了几天时间。我按照你说的做了,异常消失了。但是,如何验证一个用户没有通过表单再次添加相同的 Flavor?即既然 FlavorForm 中排除了 'user' 字段,那如何验证模型 Flavor 中的 unique_together 呢?
    • 我不太确定你在问什么;这就是您在 clean 中明确执行的操作,使用您在实例化时传入的 user kwarg。
    【解决方案2】:

    我删除了 post 方法并覆盖了 FlavorForm 中的 clean 方法以保证唯一性。

    【讨论】:

      猜你喜欢
      • 2011-08-07
      • 2020-08-25
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2015-07-10
      相关资源
      最近更新 更多