2

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?

Ledorub
  • 354
  • 3
  • 9
pirr
  • 445
  • 1
  • 8
  • 15

1 Answers1

5

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.

Shang Wang
  • 24,909
  • 20
  • 73
  • 94
  • I've already shared the link in my answer, maybe you need to read the whole page, it's not a lot. It explains how to verify the django form. You shouldn't use your way anymore, it's guaranteed not working. – Shang Wang Jan 11 '16 at 17:16
  • Maybe checkout this answer that explains in details: http://stackoverflow.com/questions/7948750/custom-form-validation – Shang Wang Jan 11 '16 at 17:20