[Answered ]-Django model forms – multiple models

1👍

When using modelforms, I don’t think it is possible to reference more than one model per modelform. You could create a custom form from forms.Form to handle the validation. When this comes up for me, I usually just use two/three/four modelforms, because I like consistency, and it keeps management at the template level easier.

For your second question, you need to override the clean() method of the modelform you care about. Here’s an example of one I wrote recently:

def clean(self):
    cleaned_data = self.cleaned_data
    npv = cleaned_data.get("npv")
    irr = cleaned_data.get("irr")
    if npv == irr:
        raise forms.ValidationError('Must have either an NPV or IRR entry.')
    if (npv != None) and (irr != None):
        raise forms.ValidationError('Must have only one entry, either NPV or IRR.')
    return cleaned_data

There are docs on overriding clean as well:

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overiding-clean-on-a-model-formset

Edit:

By this, “I usually just use two/three/four modelforms” I mean I create modelforms for each model. I instantiate them at the view level and I send them as part of the context to the template:

a = ModelFormA()
b = ModelFormB()
c = ModelFormC()

c = {'a':a,'b':b,'c':c}
return rendertoresponse('template.html',c)

if some of your models have the same column names, just use the prefix argument when you instantiate.

Docs on prefix are found here:

https://docs.djangoproject.com/en/dev/ref/forms/api/#prefixes-for-forms

then you can just pass request.POST into each of the modelforms without having to parse out fields individually.

1👍

You can use generic form classes to give you forms that will contain dropdowns for the one to many fields.

To validate form level see here: https://docs.djangoproject.com/en/dev/ref/forms/validation/#form-and-field-validation

Essentially, if all of your field level validations pass, django can check if the whole form passes test you impose (like at least 3 images)

Leave a comment