Form field validation - who renders the error? - django

I have a model which contains 2 fields of type PositiveSmallIntegerField.
And I have a ModelForm for this model and these fields.
My validation works fine. But if I type in negative number or alphanumeric string, I get the validation error as some sort of pop-up(see images below). My question: is the validation error rendered by the browser? Shouldn't the error be rendered by Django as HTML code?
And can I translate this error with django translations?
Also, in my clean method of the form I have a custom validation and I do this:
if cleaned_data['capacity_min'] > cleaned_data['capacity_max']:
raise ValidationError(_("Some message"))
I can translate this one and it is rendered as I was expected, simple HTML code in the page
Thank you
This is what happens with firefox
This is what happens with Google Chrome

These hint errors are showed by browser. Browser rejects to submit the invalid form to the server so your django validation didn't even run.
To solve this problem change the widget for you field from NumberInput to TextInput:
class MyForm(forms.ModelForm):
class Meta:
...
widgets = {
'capacity_min': forms.TextInput(),
'capacity_max': forms.TextInput(),
}

Related

Django Bootstrap Crispy InlineField with custom validation missing message

I'm using Django Crispy forms to render a fieldset containing multiple fields, most of which are not inline, but I have a date of birth field (a DateField with SelectDate Widget) which I'd like to be inline. It uses a custom validation in which is translates date to age and then checks that the user is over 18.
This validation is correct and works normally when the field is rendered in a FieldSet.
However, after applying crispy_forms.bootstrap.InlineField, with no options, just simply:
Layout(
Fieldset(
#Other fields...
InlineField('dob'),
)
)
The message does not display - though validation still works:
How do I get this message to appear while using InlineField?
InlineField doesn't support showing error from form.

django formset - dont submit a single form if a checkbox is not true?

I have a formset displayed as a table, and I do not want to validate any of the forms that do not have a specific checkbox ticked. However when the formset is submitted they are getting validated.
Do I need to handle this at the clean_field() method level?
If so how do I stop the form at that point, without rendering the whole formset invalid??
class HILISForm(forms.ModelForm):
summary = forms.CharField(
widget=forms.Textarea(attrs={'rows':3, 'cols':70}),
label='',
required=False)
class Meta:
model = Report
fields = ('reported', 'summary', )
def clean_reported(self):
reported = self.cleaned_data['hilis']
if reported:
return(hilis_reported)
else:
raise(forms.ValidationError('Not checked...'))
if I 'pass' instead of raising the error- then this form still appears in my cleaned_dict which I do not want.
I'm sure there is a much easier and cleaner way to do it, but if you get stuck you could do it by creating an id for each input field, and then creating/saving the object with your logic in the view instead. It looks like you have a lot of things to check and wouldn't be ideal, but is one way to do it.
I had a tricky validation scheme for one of my projects and found it easier to just create the form, and then process it in the view on post. You can still add error messages to the form and do all of that from the view also.

django: raise an error similar to EmailField

When using an email field, attempting to submit a form with an invalid email address raises and error like this:
What I like about this:
doesn't reload the page, rather doesn't submit at all and instead displays an error
the look
Here is what I am able to accomplish currently with Name and Password (CharFields)
The "A name is needed!" and "This field is required" messages only display after the form is submitted, which is not as sleek as displaying without the form even needing to be submitted.
The popup that you see for the email it is not django validation. It is the build in in-browser html5 email field checking (and some older browsers will not do it for you).
And you can't get any kind of validation in html5, but for checking field presents you can add required attribute to the rendered input field.
There are several ways to add attibutes to widgets in django. take a look to the How do I get Django forms to show the html required attribute? and select appropriate for you.
kmmbvnr directed me to what I was looking for. To add the type of validation I was looking for, add code similar to that below:
class UserForm(forms.ModelForm):
...
username = forms.CharField(
widget=forms.TextInput(attrs={'required': 'true'}),#HERE
)
password = forms.CharField(
widget=forms.PasswordInput(attrs={'required': 'true'}),#OR HERE
)
...

How to set django formsets _all_ error from view?

Description :
Okay, so formset is a set of forms. I basically have some number, or form where i get this number from and then i compare it to summed number from all the forms from the formset. That's why i do part of validation in a view. And if those numbers don't match i want to set error , not to a specific form in a formset, but to formsets all errors.
I have no problem setting ordinary forms error from the view :
form.errors['__all__'] = form.error_class(["Here is your error"])
But how do i assign all error to formset, and is this even possible, or i have to assign this error to forms within the formset ?
Formsets also have an errors attribute that works identically to form.errors.
However, it sounds like you're trying to do validation in your view. You should add the custom validation to the formset itself using the clean method, and raise forms.ValidationError when the user input is invalid. See the Django formset documentation.

Django model field validation without a custom form

I am using a django DateField in my model.
class CalWeek(models.Model):
start_monday = models.DateField(verbose_name="Start monday")
I have a custom validation method that is specific to my modelField: I want to make sure that it is actually a Monday. I currently have no reason to use a custom ModelForm in the admin--the one Django generates is just fine. Creating a custom form class just so i can utilize the clean_start_monday(self)1 sugar that django Form classes provide seems like a lot of work just to add some field validation. I realize I can override the model's clean method and raise a ValidationError there. However, this is not ideal: these errors get attributed as non-field errors and end up at the top of the page, not next to the problematic user input--not an ideal UX.
Is there an easy way to validate a specific model field and have your error message show up next to the field in the admin, without having to use a custom form class?
You can look into Django Validators.
https://docs.djangoproject.com/en/dev/ref/validators/
You would put the validator before the class, then set the validator in the Field.
def validate_monday(date):
if date.weekday() != 0:
raise ValidationError("Please select a Monday.")
class CalWeek(models.Model):
start_date = models.DateField(validators=[validate_monday])