I have a very simple Class Based View:
In views.py:
class IncidentEdit(UpdateView):
model=Incident
fields = visible_field_list
sucess_url = '/status'
works fine as-is. I have associated CreateView
, DeleteView
, etc. I can create edit and delete records. Now to fine-tune the project, I need to add field validation.
My question: Where do I put basic validation code when I have based the view on the 'model='
rather than 'form='
?
I could change everything to use form based views, but the whole idea was to keep it simple and it works, I just don't have the form validation except for basic 'Field Required' type validation that was defined in the model declaration.
For example, I need to make sure that one field equals the sum of two other fields. Like,
ClassRoomTotal = NumBoys + NumGirls
and raise a validation error
for the ClassRoomTotal
field if the sum doesn't match the total.
Thanks in advance.
I know it is a simple answer.
Suggestions like, "You can't do that, you have to use form=IncidentForm
and define a form class." would help.
class IncidentEdit(UpdateView):
...
def form_valid(self, form):
if form.cleaned_data['email'] in \
[i.email for i in Incident.objects.exclude(id=get_object().id)]:
# Assume incident have email and it should be unique !!
form.add_error('email', 'Incident with this email already exist')
return self.form_invalid(form)
return super(IncidentEdit, self).form_valid(form)
Also, hope this link would be useful. http://ccbv.co.uk/projects/Django/1.7/django.views.generic.edit/UpdateView/
Well,
you can't do that, you have to use
form = IncidentForm
or at least it is the simplest solution.
Note that you have to use form_class = IncidentForm
, not form = IncidentForm
and keep model = Incident
.
I don't see using ModelForm
as something that will increase your project's complexity, this is exactly their use case. Doing it another way would be making things complex.
It can be as simple as:
class IncidentForm(ModelForm):
class Meta:
model = Incident
# Define fields you want here, it is best practice not to use '__all__'
fields = [...]
def clean(self):
cleaned_data = super(IncidentForm, self).clean()
field_1 = cleaned_data.get('field_1')
field_2 = cleaned_data.get('field_2')
field_3 = cleaned_data.get('field_3')
# Values may be None if the fields did not pass previous validations.
if field_1 is not None and field_2 is not None and field_3 is not None:
# If fields have values, perform validation:
if not field_3 == field_1 + field_2:
# Use None as the first parameter to make it a non-field error.
# If you feel is related to a field, use this field's name.
self.add_error(None, ValidationError('field_3 must be equal to the sum of field_1 and filed_2'))
# Required only if Django version < 1.7 :
return cleaned_data
class IncidentEdit(UpdateView):
model = Incident
form_class = IncidentForm
fields = visible_field_list
success_url = '/status'
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