0

我有 2 个使用一对一关系相互关联的模型。如果一个模型的对象已经与另一个模型相关,我如何显示验证错误。

假设我有 2 个模型

   Class Place(models.Model):
        field1 = CharField()
        field2 = CharField()

   Class Restaurant(models.Model):
       related_field = OneToOneField(Place)
       field3 = CharField()

就我而言,一个地方一个餐厅如果用户为同一个地方提交新餐厅,那么验证应该引发

如果 Restaurant 对象已经附加到 Place 对象,那么对于同一个 Place 对象的第二家 Restaurant,我想显示验证

在管理员中,我们通常会看到这条消息“这个地方的餐厅已经存在。 ”但是我如何使用带有通用视图的模型表单来实现同样的效果

 class RestaurantCreateView(CreateView):
       form_class = RestaurantForm
       template_name = 'restaurant_create.html'

       def get_success_url(self):
           return reverse_lazy('restuarants', args=[self.object.id])

       def get_place(self, **kwargs):
           id = self.kwargs['pk']
           place = Place.objects.get(id=id)
           return place 

       def get_context_data(self, **kwargs):
           context = super(RestaurantCreateView, self).get_context_data(**kwargs)
           place = self.get_place()
           context['place'] = place
           return context

       def form_valid(self, form):
          self.object = form.save(commit=False)
          place = self.get_place()
          self.object.place = place
          self.object.save()
          return HttpResponseRedirect(self.get_success_url())

如何在基于类的通用视图中执行一对一关系验证?

4

1 回答 1

3

然后你需要将Place对象传递到你的Restaurant表单中。表单验证无法访问视图中定义的这些内容,除非您明确将数据传递给它。

class MyForm(forms.ModelForm):
    class Meta:
         model = Restaurant

    def __init__(self, *args, **kwargs):
        self.place = kwargs.pop('place', None)
        super(MyForm, self).__init__(*args, **kwargs

    def clean_related_field(self):
        place = self.place
        try:
            place.restaurant
        except Restaurant.DoesNotExist:
            return place
        raise forms.ValidationError("Restaurant already exists for that book")


class MyView(...):
    form_class = MyForm

    def get_form_kwargs(self):
        kwargs = super(MyView, self).get_form_kwargs()
        kwargs['place'] = Place.objects.get(id=self.kwargs['pk'])
        return kwargs

{% if form.related_field.errors %}.........{% endif %}

另一种方法是在 form_valid() 中伪造验证并设置错误字典,然后返回响应。这种方法可能更可取,因为它包含更多内容。此外,特别是如果您不使用表单字段,您不妨在上下文中添加一个错误标志。

class MyView():
    def form_valid(self, form):
        if Restaurant.objects.filter(related_field=self.get_place()):
            ctx = self.get_context_data(form=form)
            ctx['massive_error'] = True
            return self.render_to_response(ctx)
于 2012-09-02T08:01:27.507 回答