Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Form field initial value on failed validation

how do I set the value of a field element after a form has been submitted but has failed validation? e.g.

if form.is_valid():
    form.save()
else:
    form.data['my_field'] = 'some different data'

I don't really want to put it in the view though and would rather have it as part of the form class.

Thanks

like image 466
John Avatar asked Mar 12 '10 11:03

John


People also ask

How do I display validation error in Django?

To display the form errors, you use form. is_valid() to make sure that it passes validation. Django says the following for custom validations: Note that any errors raised by your Form.

What is initial in form in Django?

Method 2 – Adding initial form data using fields in forms.py One can add initial data using fields in forms.py. An attribute initial is there for this purpose. In forms.py, from django import forms. class GeeksForm(forms.Form):

How does Django validate form data?

Django forms submit only if it contains CSRF tokens. It uses uses a clean and easy approach to validate data. The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.

What is cleaned_data Django?

cleaned_data returns a dictionary of validated form input fields and their values, where string primary keys are returned as objects. form. data returns a dictionary of un-validated form input fields and their values in string format (i.e. not objects).


3 Answers

The documentation says:

If you have a bound Form instance and want to change the data somehow, or if you want to bind an unbound Form instance to some data, create another Form instance. There is no way to change data in a Form instance. Once a Form instance has been created, you should consider its data immutable, whether it has data or not.

I cannot really believe that your code works. But ok. Based on the documentation I would do it this way:

if request.method == 'POST':
    data = request.POST.copy()
    form = MyForm(data)
    if form.is_valid(): 
        form.save() 
    else: 
        data['myField'] = 'some different data'
        form = MyForm(initial=data)
like image 182
Felix Kling Avatar answered Nov 05 '22 18:11

Felix Kling


I ended up doing

if request.method == 'POST':
    new_data = request.POST.copy()
    form = MyForm(data=new_data)
    if form.is_valid(): 
        form.save() 
    else: 
        new_data['myField'] = 'some different data'

Hope this helps someone

like image 39
John Avatar answered Nov 05 '22 19:11

John


You can put it in the form class like this:

class MyForm(forms.Form):

    MY_VALUE = 'SOMETHING'
    myfield = forms.CharField(
        initial=MY_VALUE,
        widget=forms.TextInput(attrs={'disabled': 'disabled'})

    def __init__(self, *args, **kwargs):

        # If the form has been submitted, populate the disabled field
        if 'data' in kwargs:
            data = kwargs['data'].copy()
            self.prefix = kwargs.get('prefix')
            data[self.add_prefix('myfield')] = MY_VALUE
            kwargs['data'] = data

        super(MyForm, self).__init__(*args, **kwargs) 

The way it works, is it tests to see if any data has been passed in to the form constructor. If it has, it copies it (the uncopied data is immutable) and then puts the initial value in before continuing to instantiate the form.

like image 33
seddonym Avatar answered Nov 05 '22 20:11

seddonym