简体   繁体   English

如何在Django CreateView中处理错误

[英]How to Handle Error during Django CreateView

Using Django, I have a model and a class based view based on the provided CreateView class. 使用Django,我有一个模型和一个基于提供的CreateView类的基于类的视图。 Everything works fine - I can have a template that renders the form, validation occurs, the data is properly saved and the success_url redirected to on completion. 一切正常-我可以有一个模板来呈现表单,进行验证,正确保存数据,并在完成时将success_url重定向到。

The problem occurs in that I have a unique_together constraint on two of the fields. 发生问题的原因在于我对两个字段都有一个unique_together约束。 If this error is hit, it appears that form_valid() doesn't catch it, and an error page is produced instead. 如果发生此错误,则似乎form_valid()无法捕获它,而是生成了一个错误页面。

My goal is to be able to catch this ahead of time and return the user to the form - with the data filled in from their last attempt - and display a message to them. 我的目标是能够提前捕获到该错误,然后将用户返回到表单(使用上次尝试填写的数据)并向他们显示一条消息。 Feels like this should be simple, and I added code to form_valid() in the view to identify the problem, but I have no clue what to do next. 这样的感觉应该很简单,我在视图中向form_valid()添加了代码以识别问题,但是我不知道下一步要做什么。

A redirect doesn't work because I can't add the context in (or can I?) and I really don't want to put everything in the URL. 重定向不起作用,因为我无法在其中添加上下文(或者可以吗?),并且我真的不想将所有内容都放入URL中。 Any ideas where to look? 有什么想法在哪里看?

The Model: 该模型:

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'),)

The View: 风景:

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)

The snippet URL config: 片段网址配置:

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

And the error: 错误:

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

Thanks @geckos... that pointed me in the right direction. 谢谢@geckos ...这为我指明了正确的方向。 Adding the following to my View did the job: 在我的视图中添加以下内容即可完成此工作:

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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM