1

I've got a couple models like Listing, Image (one to many to listing), Category (one to many to listing), etc.

How can I have a form that deals with all these models? Also, how can I enforce non row specific validation like say: require that at least three images are passed/associated with a listing?

2 Answers 2

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.

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

2 Comments

Could you elaborate a bit more on what you mean by 'I usually use two/three/four modelforms'? You mean use the separate modelforms in the view? Wrap the modelforms in a form? -- Also, in the modelform clean() method, does cleaned_data contain just the current record data or all passed records?
@RS7, yes but you can always query within the formitself too. I'll add an example like that to the bottom of my answer in a minute. Also edited the above for the first part of your question here
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)

1 Comment

So create a generic form, mirror the fields in a model, create a clean() to check number of images an create a save() to assign values to the respective models? How would I handle/validate FK constraints?

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.