1

Let's say I have a Django form with ChoiceField:

class MyForm(forms.Form):
    name = forms.CharField(label="Name", required=True)
    some_object = forms.ChoiceField(label="Object", choices=[(0, '-----')] + [(x.id, x.name) for x in Obj.objects.all()])

Choisefield is being initialized with list of objects headed by 'empty choice'. There is no object with pk=0. In that form I have a clean() method:

def clean(self):
    if not Obj.objects.filter(self.cleaned.data['some_object'].exists():
        self.errors.update({'some_object': ['Invalid choice']})

It works well when I'm sending a form to a server, if data in it doesn't match conditions, field.is_valid returns False and I render form with error messages. But, when I create an empty form like this:

if request.method == 'GET':
    data = {'name': 'Untitled',
            'some_object': 0}
    form = MyForm(data)
    return render(request, 'app\template.html', {'form': form})

Django renders form with error message ('Invalid choice') even though form was just created and 'Object' select was intended to be set in empty position. Is it possible to disable form clean() method in specific cases? Or maybe I'm doing this all wrong? What is the best practice to create an empty form?

1
  • 2
    Any reason you are not using a ModelForm or at least a ModelChoiceField? It seems like you are replicating something that django already offers. Commented Feb 3, 2019 at 20:58

1 Answer 1

2

The problem is that a form with any data dictionary passed to it counts as a "bound" form, against which Django will perform data validation. See here for details: https://docs.djangoproject.com/en/2.1/ref/forms/api/#bound-and-unbound-forms

You want an "unbound" form - to have default initial values in here, just set the initial property on your form fields. See full details here: https://docs.djangoproject.com/en/2.1/ref/forms/fields/#initial

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.