Issue
I try override clean method for model form with foreign key.
Model:
class Doc(Model):
name = CharField()
doc_type = ForeignKey(DictDocType)
Form:
class DocForm(ModelForm):
class Meta:
model = Doc
fields = '__all__'
def clean_doc_type(self)
doc_type_name = self.cleaned_data['doc_type']
try:
DictDocType.objects.get(name=doc_type_name)
except DictDocType.DoesNotExist:
msg = '{0} does not exist in dictdoc {1}.'.format(
doc_type_name, self.cleaned_data['name'])
raise ValidationError(msg)
return name
In the test I get an error:
KeyError: 'name'.
If I remove self.cleaned_data['name']
from msg
- I do not get self.cleaned_data['doc_type']
.
Where I'm wrong?
Solution
You can't cross reference other fields in clean_foo
methods, because not all fields' clean_foo
methods are called when you are in one of them. There might be some values of the form that are not populated yet, so clean_name()
is not yet called when you call clean_doc_type()
, thus you don't have self.cleaned_data['name']
.
This should be done in clean
method. Django doc very explicitly documented this:
By the time the form’s clean() method is called, all the individual field clean methods will have been run (the previous two sections), so self.cleaned_data will be populated with any data that has survived so far. So you also need to remember to allow for the fact that the fields you are wanting to validate might not have survived the initial individual field checks.
Also, your clean method doesn't make much sense and not necessary at all. You wouldn't able to choose a foreignkey
that doesn't exist in ModelForm
. Even if you force the front end to do so, the field would auto fail the validation and give error:
Select a valid choice. foo is not one of the available choices.
Answered By - Shang Wang
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.