A. Amirov
A. Amirov

Reputation: 23

Two ModelForms in one CreateView

This probably have no sense, but it's better to get advice how to implement this behavior properly.
I have User model and two others (let it be A and B). Both A and B have ForeignKey to User. On User creation I also create A and B for this User:

def save(self, *args,  **kwargs):
    user_id = self.id
    super(User, self).save(*args, **kwargs)
    if user_id is None:
        as_A = A(user=self)
        as_A.save()
        as_B = B(user=self)
        as_B.save()

The only required field in A and B is user = models.OneToOneField(User), others are optional.

class A(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    x = models.CharField(max_length=100, blank=True)

class B(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    y = models.CharField(max_length=100, blank=True)

I want to provide two forms for registration: as A or as B. In registration form as A, customer should be able to set fields for A model entity related to User. Similar for B.

This is my RegistrationForm:

class RegistrationForm(forms.ModelForm):
    password = forms.CharField(
        strip=False,
        widget=forms.PasswordInput,
    )
    confirm_password = forms.CharField(
        strip=False,
        widget=forms.PasswordInput
    )

    class Meta:
        model = User
        fields = ['email', 'first_name', 'password']

    def clean(self):
        cleaned_data = super(RegistrationForm, self).clean()
        password = cleaned_data.get("password")
        confirm_password = cleaned_data.get("confirm_password")
        if password != confirm_password:
            raise forms.ValidationError("Passwords are not same")
        return cleaned_data

As you can see it contains only User fields.

How to implement properly additional forms and view?

Upvotes: 1

Views: 169

Answers (1)

Astik Anand
Astik Anand

Reputation: 13047

Use MultiModelForm from django-betterforms. This will help you achieve what you want to do.

Upvotes: 1

Related Questions