I have a Django form that will add an entry to a database with a unique constraint on one of the columns. If the submission happens to attempt creation of a duplicate, I get a django.db.utls.IntegrityError
stating I violated the unique constraint (thankfully).
When processing Django forms, there are a number of ways to validate:
clean
methodclean_<field>
methodIf the clear_<field>
method raises a django.forms.ValidationError
, the error message will be appended to a list in the _errors
dictionary under the field's name. When using the clean
method, errors should be manually inserted into the _errors
dict.
Now, the clean
and clean_<field>
methods don't sound like a nice place to put code that has side effects, and I fear that checking at this moment whether the value is unique does not guarantee I won't get IntegrityError
s. I would prefer to actually try and create the row in the database and signal a form error when a constraint is violated.
My main problem is that forms expose a public property errors
which is read-only. Therefore, I should, according to the docs, add a method in my form that does all the work, try to insert in the database and register an error when an IntegrityError
is raised. Because the action that processes the form after validation requires lots of other data, I don't want to put the code inside the form class itself.
Is there any other (documented or not) way to go about adding an entry in the errors
dict from outside the class, or should I simply access the _errors
"private" variable and be happy with that? I know this sounds like an OOP breach, but creating an extra method just to access this "private" variable does not seem to me like it shields anybody from anything.
Edit:
Seems like someone else already raised a similar question, but it seems the answers pointed to manual insertion into _errors
...
The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.
Checking which form data has changed Use the has_changed() method on your Form when you need to check if the form data has been changed from the initial data. has_changed() will be True if the data from request. POST differs from what was provided in initial or False otherwise. The result is computed by calling Field.
A Form instance has an is_valid() method, which runs validation routines for all its fields. When this method is called, if all fields contain valid data, it will: return True. place the form's data in its cleaned_data attribute.
cleaned_data returns a dictionary of validated form input fields and their values, where string primary keys are returned as objects. form. data returns a dictionary of un-validated form input fields and their values in string format (i.e. not objects).
For now, a simple solution is the following:
try:
# Try to save model instance, which might throw `IntegrityError`.
# ...
except django.db.utils.IntegrityError:
# The form passed validation so it has no errors.
# Use the `setdefault` function just in case.
errors = django.forms.util.ErrorList()
errors = form._errors.setdefault(
django.forms.forms.NON_FIELD_ERRORS, errors)
errors.append('Sorry, this username is already in use.')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With