I need to be show custom error message for invalid forms. I don’t know how to do it in class based views so I can show it to my html template. here is my class based views:
class EditPatient(UpdateView):
model = Patient
form_class = PatientUpdateFrom
template_name = 'hospital/edit-patient.html'
def form_valid(self, form):
error_message = None
if form.is_valid():
name = self.request.POST["patient_name"]
email = self.request.POST["phone"]
if len(name) > 20:
error_message = 'maximum 20 character allowed in name'
if len(phone) > 20:
error_message = 'maximum 15 character allowed in phone'
""" #I tried this but didn't work
def get_context_data(self, **kwargs):
context = super(EditPatient,self).get_context_data(**kwargs)
context['error_message'] = error_message
return context
"""
if not error_message:
messages.add_message(self.request, messages.INFO, 'Patient Sucessfully Updated')
form.save()
return redirect('hospital:edit-patient',self.object.slug)
Doing the validation in form_valid is beyond the point where this should be done. Form_valid is intended to be called after all validation is performed and assumes that the form at that point is good.
KenWhitesell here I am actually updating few fields of my another model. So I can raise validation error for PatientUpdateFrom but how to show error message for custom fields which not related with PatientUpdateFrom where I am getting input for updating fields for another model.
I am not using form for few fields. Assume here I am getting input for name and email which belongs from another model and I am not using any form fields. see the below example:
if not error_message:
messages.add_message(self.request, messages.INFO, 'Patient Sucessfully Updated')
form.save()
UserProfile.objects.filter(acess_patient_model=form.instance).update(name=name,email=email)
how to show my custom error message for name and email? In function based view normally I passed the context somethings like this:
if len(name) > 20:
error_message = 'maximum 20 character allowed in name'
context{'error_message':error_message}
if not error_message:
messages.add_message(self.request, messages.INFO, 'Patient Sucessfully Updated')
form.save()
UserProfile.objects.filter(acess_patient_model=form.instance).update(name=name,email=email)
how to show my custom error message for name and email? In function based view normally I passed the context somethings like this:
if len(name) > 20:
error_message = 'maximum 20 character allowed in name'
context{'error_message':error_message}
Ok, there’s too much information missing from talking in the abstract here. We’ll need to see the complete view at this point, along with the form involved.
The snippet you posted shows two data elements being pulled from the data being posted, which should be form fields, and therefore validated by the form. Quite frankly, if you’re doing it any other way, you’re not using the form and views as designed.
class EditPatient(UpdateView):
model = Patient
form_class = PatientUpdateFrom
template_name = 'hospital/edit-patient.html'
def form_valid(self, form):
error_message = None
if form.is_valid():
name = self.request.POST["patient_name"]
email = self.request.POST['email']
phone = self.request.POST['phone']
gender = self.request.POST['gender']
country = self.request.POST['country']
state = self.request.POST['state']
city = self.request.POST['city']
zip_code = self.request.POST['zip_code']
address = self.request.POST['address']
birth_date = self.request.POST['date_of_birth']
date_time_obj = datetime.datetime.strptime(birth_date, "%Y-%m-%d")
email = str(email)
phone = str(phone)
gender = str(gender)
country = str(country)
state = str(state)
city = str(city)
zip_code = str(zip_code)
address = str(address)
gender_choice = ['Male','Female','Other']
if len(email) > 300:
error_message = 'maximum 300 character allowed in email'
if len(phone) > 20:
error_message = 'maximum 20 character allowed in phone'
if len(gender)>10:
error_message = 'maximum 10 character allowed in gender'
if len(country)>100:
error_message = 'maximum 100 character allowed in country'
if len(state)>100:
error_message = 'maximum 100 character allowed in state'
if len(city)>100:
error_message = 'maximum 100 character allowed in city'
if len(zip_code)>100:
error_message = 'maximum 100 character allowed in zip code'
if len(address)>1000:
error_message = 'maximum 1000 character allowed in address'
if gender not in gender_choice:
error_message = "please select gender"
if phone == "":
error_message = "please enter phone number"
if email == "":
error_message = "please enter email"
if date_time_obj > datetime.datetime.today():
error_message = "Birth date can't be future"
date_time_obj = date_time_obj.date()
calculate_age = age(date_time_obj)
if not error_message:
messages.add_message(self.request, messages.INFO, 'Patient Sucessfully Updated')
form.save()
UserProfile.objects.filter(acess_patient_model=form.instance).update(age=calculate_age,date_of_birth=date_time_obj,email=email,phone=phone,gender=gender,country=country,state=state,city=city,zip_code=zip_code,address=address)
return redirect('hospital:patient-details',self.object.slug)
return redirect('hospital:edit-patient',self.object.slug)
PatientUpdateFrom
class PatientUpdateFrom(forms.ModelForm):
patient_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}),required=True)
class Meta:
model = Patient
fields = ['patient_name']
def clean_patient_name(self):
patient_name = self.cleaned_data['patient_name']
if len(patient_name) > 100:
raise forms.ValidationError("Maximum 100 character allowed")
return patient_name
How to render my error_message in my html template ?
These should all be fields in your form. (A ModelForm is not limited to only the fields in the model. You can add additional fields as necessary.) This allows you to do proper form validation and error-message handling.
As you said ModelForm is not limited to only the fields in the model. But it’s only rising validation error only for for doctor_name which coming from my Doctor model. How to raise validation error for email which coming from another model?
class DoctorFrom(forms.ModelForm):
class Meta:
model = Doctor
fields = ['doctor_name']
def clean_doctor_name(self):
doctor_name = self.cleaned_data['doctor_name']
if len(doctor_name)>1:
raise forms.ValidationError('maximum 100 character allowed')
return doctor_name
def clean_email(self):
email = self.cleaned_data['email']
if len(email)>3:
raise forms.ValidationError('maximum 300 character allowed')
return email
You can’t create two Meta classes in one form, nor can you create one Model Form from two different models.
If you’re going to use Model Forms for two different models, you need to create a Model Form for each model.
There’s too much information missing from your posts at this point. I know you’ve been making a lot of changes, and I can’t follow what’s going on from all the various snippets posted previously.
Please post the current and complete forms, views, models and templates involved with this process at the moment.
KenWhitesell I got your point. We need to be use separate Model Form for each model. Right now it’s difficult to explain my all model, views and forms. I got your point.