0

One to One Relation を使用して相互に関連付けられている 2 つのモデルがあります。あるモデルのオブジェクトが既に別のモデルに関連付けられている場合、検証エラーを表示するにはどうすればよいですか。

2つのモデルがあるとします

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

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

私の場合、1つの場所に1つのレストランユーザーが同じ場所の新しいレストランを送信すると、検証で発生するはずです

Restaurant オブジェクトが既に Place オブジェクトにアタッチされている場合、同じ Place オブジェクトの 2 番目の 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())

クラスベースのジェネリックビューで1対1の関係検証を実行するにはどうすればよいですか?

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 %}

もう1つのアプローチは、form_valid()で検証を偽造し、エラーdictを設定して、応答を返すことです。この方法は、はるかに多く含まれているため、好ましい場合があります。また、特にフォームフィールドを使用していない場合は、コンテキストにエラーフラグを追加することもできます。

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 に答える