2017-12-11 5 views
0

Djangoを使用して、提供されているCreateViewクラスに基づいてモデルとクラスベースのビューを作成しました。すべて正常に動作します - フォームをレンダリングするテンプレートを持つことができ、検証が行われ、データが正しく保存され、success_urlが完了時にリダイレクトされます。Django CreateViewでエラーを処理する方法

この問題は、2つのフィールドでunique_together制約が発生するという問題が発生します。このエラーが発生した場合は、form_valid()がそれをキャッチせず、代わりにエラーページが生成されます。

私の目標は、これを前もってキャッチして、ユーザーに最後の試行時に入力したデータをフォームに戻し、メッセージを表示できるようにすることです。このような感じはシンプルでなければならず、問題を特定するためにビューのform_valid()にコードを追加しましたが、次に何をすべきかわかりません。

コンテキストを追加できない(またはできますか?)ため、リダイレクトは機能しません。本当にすべてをURLに入れたくありません。任意のアイデアを見てどこですか?

モデル:

class Client(BaseModel): 
    name = models.CharField(max_length=240, db_index=True, verbose_name='Client Name') 
    organization_link = models.ForeignKey(Organization, on_delete=models.PROTECT, verbose_name='Organization') 
    client_group_link = models.ForeignKey(ClientGroup, blank=True, on_delete=models.SET_NULL, null=True, verbose_name='Client Group') 
    policy_link = models.ManyToManyField(OrganizationPolicy, related_name='attached_clients', verbose_name='Policies') 
    active = models.BooleanField(default=True, db_index=True, verbose_name='Active') 

    class Meta: 
     unique_together = (('name', 'organization_link'),) 

ビュー:

class ClientCreateView(CreateView): 
    model = Client 
    fields = ['name', 'client_group_link', 'active'] 
    success_url = reverse_lazy('entities_client_roster') 

    def form_valid(self, form): 
     organization = get_object_or_404(Organization, id=self.kwargs['organization']) 
     form.instance.organization_link_id = organization.id 
     return super().form_valid(form) 

スニペットURLの設定:

url(r'^client_create/(?P<organization>[0-9a-f-]+)', 
    ClientCreateView.as_view(template_name='entities/client_create.html'), 

とエラー:

IntegrityError at /accept/client_create/xxx 
duplicate key value violates unique constraint "app_entities_client_name_organization_link_id_5e612e47_uniq" 
+0

あなたが言っているエラーページのテンプレートコードを投稿してください。 –

+0

ok - コードが掲載されました。テンプレート自体は、フォームを提出するだけでレンダリングされ、同じ名前を2回入力しない限り、新しいレコードを投稿するために正常に動作します。 –

+0

ちょっと推測して、ポストメソッドを上書きし、ブロック以外のtryを使ってスーパーポストを呼び出そうとします。 – geckos

答えて

0

ありがとう@ガコス...正しい方向に私を指摘しました。私のビューに以下を追加すると、仕事ができました:

def post(self, request, *args, **kwargs): 
    try: 
     super().post(request, *args, **kwargs) 
    except IntegrityError: 
     messages.add_message(request, messages.ERROR, 
          'You already have registered a Client with this name. ' + \ 
          'All of your Client names must be unique.') 
     return render(request, template_name=self.template_name, context=self.get_context_data()) 
関連する問題