Using Django, I have a model and a class based view based on the provided CreateView class. 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.
The problem occurs in that I have a unique_together constraint on two of the fields. If this error is hit, it appears that form_valid() doesn't catch it, and an error page is produced instead.
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.
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. 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. 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())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.