[Django]-UpdateView – Update a class that has OneToOne with User

3👍

This problem is actually nothing to do with class based views or update view – its a basic issue that has been there since the beginning, which is:

ModelForms only edit the fields for one model, and don’t recurse into
foreign keys.

In other words, if you have a model like this:

class MyModel(models.Model):
   a = models.ForeignKey('Foo')
   b = models.ForeignKey('Bar')
   c = models.ForeignKey('Zoo')
   name = models.CharField(max_length=200)

A model form will render three select fields, one for each foreign key, and these select fields will have all the values from those models listed – along with one text field for the name.

To solve this problem, you need to use InlineFormSets:

Inline formsets is a small abstraction layer on top of model formsets.
These simplify the case of working with related objects via a foreign
key.

You should use InlineFormSet from the excellent django-extra-views app. To do this, you’ll create a view for the related object as well:

class MyUserInline(InlineFormSet):
    model = MyUser

    def get_object(self):
        return MyUser.objects.get(user=self.request.user)


class AccountEditView(UpdateWithInlinesView):
    model = User
    inlines = [MyUserInline]

1👍

Another option is django-betterforms‘s Multiform and ModelMultiForm.

Example:

class UserProfileMultiForm(MultiForm):
    form_classes = {
        'user': UserForm,
        'profile': ProfileForm,
    }

It works with generic CBV (CreateView, UpdateView, WizardView).

Leave a comment