I do not use the form of models.form
I received and stored each items of request.POST and request.FILES
I will make my validation function.
So I wonder what validation it does. (ex. input is empty, etc.)
Manually processing request.POST and request.FILES is really a bad idea: the data can be "forged", and the HTML specifications on how the request is constructed with a <form> have some peculiarities. For example if a checkbox <input type="checkbox" name="somename"> is not checked, then it does not appear in the request, whereas if it is checked, it appears with no value in the request.
A first problem is thus that not per se all fields of the form will appear in the request.POST, that is not per se a problem: some fields might not be required. The Django form will thus check for all fields that are required, if the value appears in request.POST and request.FILES.
Next the form will start cleaning the data. This means that it converts the data, which are all strings, to a more suitable datatype. For example for a DateField, it will try to convert this to a date object. It will normally try all formats in the DATE_INPUT_FORMAT setting [Django-doc], but you can customize that when you construct a DateField to thus use a different format for that specific field. Some fields, like a BooleanField will for example look if the field is indeed in the request.POST and then return True and otherwise False, so this is not just a simple mapping of the value in request.POST, since that value might not be there.
Cleaning does not only map strings on corresponding Python objects, it can also do some (small) post-processing on these fields. For example a CharField will by default trim the string, and thus remove leading and trailing spaces, whereas a ModelChoiceField will pick the corresponding model object for that primary key from the database. A form field has also a list of empty values: values that are considered to be empty. For example for a CharField, you can set '/' as an empty value. It will then thus consider the slash as the field being empty.
One can create extra form fields than the ones that are defined, and this thus means that it is easy to construct for example an EANField where you implement the cleaning once, but that would mean that you need to do that for every view. Form fields are thus used to make cleaning more reusable by implementing the cleaning process into the field.
Next in line are validations on the form fields. While a text field in HTML can have a <input type="text" minlength="6" maxlength="24">, you can nevery rely on what the browser will post as values: indeed POST requests can be forged, so while the HTML form might intent to prevent people from picking a username with less than six characters, or more than twenty-four characters, you can not be sure that this will be the case in the POST request. A form field can be passed validators=… [Django-doc]: a set of callables that raise a validation error in case the item is not valid. For example for a CharField, if you pass a value for the min_length=… and/or max_length=… validators, it will thus check these. It will add all ValidationErrors to a list, which is often cumbersome to implement in a view: most views that validate data will check a certain condition, for example the minimum length of the characters for a password, and if that fails, report an error, whereas with a Form, it can also add an extra error that you should use at least one digit. The form will do that for all form fields, and thus construct a dictionary mapping the name of the fields to a list of errors.
If all the form fields successfully return validate the data, then the form will create an attribute .cleaned_data [Django-doc] that maps the names of the fields to the corresponding value that has been cleaned by that form field. One can however further add additional cleaning and validation to the Form.
Then there are validations at the form level itself. If you want to slightly customize the form, then form a field named field_name, you can implement a clean_field_name method. This method can access the .cleaned_data dictionary, and then run additional validation on that field and raise a ValidationError, and furthermore "clean" the function, for example by returing an object of a different type, or doing some post-processing on the data that is then returned. The Form will thus collect these values and update the dictionary with these cleaned values. Furthermore if the method raises a ValidationError, the error will be added to the .errors for that specific field.
After that, the form will call the .clean() method [Django-doc]. This will perform cleaning on the entire form. Indeed, now that all fields are cleaned individually, it might still be possible that there are errors about the combination of the fields. For example whether the two password fields match. Usually the clean method will thus work with multiple fields in the .cleaned_data attribute, and return for example that dictionary, or another object. If you raise a ValidationError here, the error will be put in the .errors under the '__all__' key, since this is not related to a specific field.
For a ModelForm [Django-doc], the validation is not over yet. Indeed, the model itself can still have some validation. It will update the instance wrapped in the form with the values of the cleaned data, and call the .full_clean() method [Django-doc] on the instance, and later also call the .validate_unique(…) method [Django-doc] to validate that for fields that should be unique (have unique=True), these are indeed unique. That last task is often more complicated than it looks at first sight, since if the instance is edited in the form, the check in the database, should exclude the current instance you are editing.
Only after all these validation, the Form or ModelForm will accept the change, and then .is_valid() will return True. If in one of the steps thus fails, the error will be added to the .errors, and thus .errors will try to construct a dictionary that tries to report all the problems with the data. This is useful if you re-render the form, since then the errors can be put next to the corresponding field, and the user thus gets feedback on all the problems with the data, not the first one encountered by the form, since that could result in a lot of attempts to eventually fix the form.
To summarize: there is a lot of logic in place in a Form to validate and clean data. Trying to implement that in a view is a popular mistake. It is cumbersome to do it correctly in a view, but it is also not very flexible: if you want to add an extra validator for a password for example, it will take a lot of work to implement that, especially if you want to that in multiple views. Forms are created to work with reusable components like form fields, validators, uniqness checks, etc. It is also quite robust since it is aimed to validate request data that might be forged, and thus was not validated properly by the HTML attributes.
I want to take row-wise input in Django forms.
The table is as shown in: Image
The rows of 'Source' field should be headings and corresponding to it should be input field belonging to 'Data' field (in html template) such that the input correspondingly goes into proper record.
When I lay out a form using {{form.as_p}}, I get something that looks a bit like this, and which seems to match what you're asking:
If that's not what you're looking for, then you'll need to set your form out manually, as specified in the documents. All of the form attributes - label, name and id are available from your form variable being passed back to the form - it's just a regular HTML form. Lay it out as you want it, and then substitute in the Django variables.
The form fields here correspond to the modelFields in my class Event in the models.py file.
First of all I have tried to research my problem but have not been able to find what I need. My problem might be related to the design of my project (any help would be appreciated).
The problem I am facing is as follows:
I have a few models
I have a model that would be used specifically to create a ModelForm
In this model I have ForeignKey field that is represented by default as a select/option input widget in the ModelForm (for each the value attribute is the ForeignKey and text between the tags is the __str__() of the model the ForeignKey points to. The user sees the __str__() and value attribute of the option tag is submitted which is great).
So far so good but I want to replace the widget with an input text field so I can implement it as a search field.
Now when the user submits the form the string entered in the text input field is submitted and of course django doesn't like that since it expects a foreign key
I already can think of a few solutions to the problem and I am sure I can make it work but each of them feels like I would be violating some best practices. So my question is what should I do?
Do I exclude this particular field from the ModelForm and implement it as an input text field then after form submission make a query with it's value and then store the ForeignKey to the DB
Do I manipulate the data with JavaScript upon submission so that Django receives correct information
Can I clean this fields data with Django and transform it from string to FK?
Am I going the wrong way with this or there is a Django feature for this type of situation?
If anyone has the same problem here is the solution (to my problem at least):
I tried to use the clean_<fieldname> method to change the user entered string to database id. The method wasn't executing because the validation process was stopping earlier because of the difference between the form field and the widget. I redefined the form field to CharField so that step of the validation was working and then the clean_<fieldname> method executes without a problem.
There exist two ways in Django to process the several forms in one request:
Form prefix
Form sets
In which use case is each one preferable?
In my specific case, the form lists the fields for an object to be updated from a diff. For each field, an action can be defined (like "update value", "keep value"). The page contains forms for several objects.
If you have several different forms classes with same input names, like a PetForm and an OwnerForm with both a name input in the same page, then you have to use a prefix as explained in the documentation you linked.
If you want to have the same form class repeated, ie. to render a table of TicketForm, then you can use Formsets directly: Formsets use the form prefix feature internally and you don't have to worry about it.
I have a model containing items, which has many different fields. There is another model which assigns a set of this field to each user using a m2m-relation.
I want to achieve, that in the end, every user has access to a defined set of fields of the item model, and he only sees these field in views, he can only edit these field etc.
Is there any generic way to set this up?
One way to do this would be to break the Item model up into the parts that are individually assignable to a user. If you have fixed user types (admin, customer, team etc.) who can always see the same set of fields, these parts would be whole groups of fields. If it's very dynamic and you want to be able to set up individual fields for each user, each field is a part of its own.
That way, you would have a meta-Item which consists solely of an Id that the parts can refer to. This holds together the parts. Then, you would map a user not to the Item but to the parts and reconstruct the item view from the common Id of the parts.
A second approach would be to not include the filtering in the model layer. I. e., you leave the mapping on the model layer as it is and retrieve the full set of item fields for each user. Then you pass the items through a filter that implements the rules.
Which approach is better for you depends on how you want to filter. If it's fixed types of users, I would probably implement a rules-based post-processor, if it's very dynamic, I would suggest the approach from my earlier answer. Another reason to put the filtering rules in the model would be if you want to reuse the model in applications that couldn't reuse your filter engine (for example if you have applications in different languages sharing the same database).