Simplest solution: write a middleware implementing process_exception that only catches IntegrityError and returns an HttpResponse with your rendered template, and make sure this middleware is after the default error handling middleware so it is called before (cf https://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception for more).
Now if I was you, I wouldn't assume such a thing as "there is only one obvious case where "IntegrityError" can arise", so I strongly recommand you do log the exception (and send email alerts) in your middleware.
class Manufacturer(models.Model):
name = models.CharField(default='', max_length=40, unique=True)
And ModelForm:
class ManufacturerForm(forms.ModelForm):
def clean(self):
cleaned_data = super(ManufacturerForm, self).clean()
name = cleaned_data.get('name')
if Manufacturer.objects.filter(name=name).exists():
raise forms.ValidationError('Category already exists')
class Meta:
model = Manufacturer
In this case when you submit name that is unique. You'll get validation error before IntegrityError. 'Category already exists' message will be shown in your form in template
For class-based views you can catch the error, add it to the error list and use FormMixin.form_invalid to re-render the form template, just as if standard validation failed:
class YourView(CreateView):
...
def form_valid(self, form):
try:
return super().form_valid(form)
except IntegrityError as e:
form.add_error(None, e)
return self.form_invalid(form)