How to set django formsets _all_ error from view? - django

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.

Related

How to throw a messages in django form that it is not changed the data in the form in UpdateView

I have a form that been populated data in Updateview i want to check or throw a message that the form hasn't had changes when clicking the submit button
I'm glad that you can help me in this matter I can't understand some logic about this.
If you use a ModelForm you can access self.instance during an update.
This allows you to compare you instance's fields with the cleaned_data to see if any is different.
Then you can raise a ValidationError if no field has been modified.

Formset validation changes Django 1.6

I had the following code working in Django 1.5:
if formset.is_valid():
formset.save()
The forms inside the formset are performing a check inside clean() to make sure that certain required fields are entered (only known at runtime). This means that although a user might not enter any values the validation would still run and ask for data entry if required.
With Django 1.6 this behaviour does not apply anymore. If there was no change then the form's clean() method does not get called anymore when calling formset.is_valid().
I could not find anything in the changelogs that would explain this new behvaiour. Is there a flag on formset.is_valid() to force the validation even if no changes were made?
It seems as if the validation was skipped since the formset changed the form's edit_permitted attribute.
The following change fixed the issue I had:
# Was required to disable shortcut for validation when
# no data was entered
for form in formset:
form.empty_permitted = False

How to partially validate form, only non-blank fields, even when they are required, in Django?

We are using some complex form workflow where we want to have a kind of Ajax prevalidation verifications all the time before final submission (and validation). So we are making an Ajax request to the server and validating the form, but not saving the results. If there are errors, we display them to the user.
But the issue is with required fields which all get marked as missing values, when they are empty (because the user has not yet finalized the form's content). So my question is, how can we make a validation run on only those fields which are not empty? For final submission we will validate all fields and catch missing fields. But for this partial validation we would like to have only filled fields validated.
One approach would be to iterate through the form fields setting required=False prior to validation. In your ajax view, something like this should work:
for field in myform.fields.itervalues():
field.required = False
json_result = json.dumps({'form_valid': myform.is_valid()})

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])

What triggers form validation for a Django formset?

I have a from based on ModelForm and use formset_factory to create a formset based on two dictionaries. There is also one extra form.
In my view, I use the formset JS plugin and I delete the two forms with data. When I POST the remaining empty extra form, it fails validation because of a required field.
I don't understand why that form is being validated. Its changed_data list is empty. It is returned with empty_permitted = False (and I'd like to know why that is), but even after I change it to True in the debugger, it is validated.
So what is triggering validation and how can I modify it?
I would also be interested to know where data like the initial data is stored. Is that somewhere in my view where I am not seeing it?
The template management form has a counter called INITIAL_FORMS. The formset plugin for adding and deleting forms does not distinguish between initially populated forms and forms it adds. When a form is deleted, if it was initially populated, then INITIAL_FORMS should be decremented.
This can be implemented by including a template variable which flags forms which are initially populated. In the removed function of the formset plugin, if one of these flagged forms is being deleted, then decrement INITIAL_FORMS.