Deadly
Deadly

Reputation: 2094

Django forms from "Generic related" models

I have some models, connected with GenericForeignKey:

Class Main(models.Model)
    filed_1      = models.CharField(max_length=20)
    object_id    = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    object       = generic.GenericForeignKey('content_type', 'object_id')

Class Additional_1(models.Model):
    f_1 = models.CharField(max_length=20)
    f_2 = models.CharField(max_length=20)

Class Additional_2(models.Model):
    d_1 = models.CharField(max_length=20)
    d_2 = models.CharField(max_length=20)

And forms for this models:

Class MainForm(forms.ModelForm):
      class Meta:
           model  = Main
           fields = ('filed_1', 'object_id', 'content_type')

           widgets = {
               'object_id': forms.HiddenInput,
               'content_type': forms.HiddenInput
           }

Class Additional_1Form(forms.ModelForm):
    class Meta:
        model  = Additional_1
        fields = ('f1', 'f2')

Class Additional_2Form(forms.ModelForm):
    class Meta:
        model  = Additional_2
        fields = ('d1', 'd2')

How to make forms, composed of fields of MainForm + Additional_iForm in one html form with one submit button (MainForm + Additional_1Form and Main + Additional_2Form) and provide correct creating and editing. There is way to do it using standard Django components, like inline formset for ForeignKey?

P.S. I think the answer to this question should be contained in this section of the documentation, but there is too little information to answer. https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#generic-relations-in-forms-and-admin

EDITION #1

# This is always false, because of 'object_id' in main_form
if main_form.is_valid() and additional_1_form.is_valid():
    additional = additional_1_form.save()
    main_form.object_id = additional .id # I need something like this to set object_id 
    main_form.save()

Upvotes: 3

Views: 1499

Answers (1)

Simeon Visser
Simeon Visser

Reputation: 122376

Create one form tag:

<form action="..." method="POST">
{{ main_form }}    
{{ additional_form_1 }}    
{{ additional_form_2 }}
<input type="submit" value="Submit!">
</form>

where {{ mainform }}, {{ additional_form_1 }} and {{ additional_form_2 }} are the HTML that Django generates for each of each of the forms. You can add editing feedback or additional functionality using JavaScript (such as filling in values when the user has selected a particular value for a particular field).

In the back-end, you can then check whether each of the forms is valid:

if (main_form.is_valid() and
   additional_form_1.is_valid() and
   additional_form_2.is_valid()):
   pass

If not, you can display errors in the form page again.

Upvotes: 1

Related Questions