1

I use UpdateView to update user account. User consists of User and UserProfile like this:

class UserProfile(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE,related_name='userprofile')
    telephone = models.CharField(max_length=40,null=True)

Now, I've created a class UpdateView to be able to update for example UserProfile - telephone which works.

FORM:

class UserProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('telephone',)

URLS:

url(r'^edit-profile$',view=views.UserUpdate.as_view(),name='user_update'),

VIEW:

# @login_required
class UserUpdate(UpdateView):
    form_class = UserProfileUpdateForm
    context_object_name = 'user_update'
    template_name = 'auth/profiles/edit-profile.html'
    success_url = 'success url'

    def get_object(self,queryset=None):
        return self.request.user.userprofile

    def form_valid(self, form):
        #save cleaned post data
        clean = form.cleaned_data
        self.object = form.save()
        return super(UserUpdate, self).form_valid(form)

Now, I want to be able to change some attributes which belongs to User and some attributes which belongs to UserProfile.

I've already tried to change UserProfileUpdateForm fields variable but It does not work at all...

class UserProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('telephone','model.user.first_name',) <- this does not work, I want to add to the form attribute 'first_name' which belongs to User, not UserProfile

Do you know what to do to be able to change telephone, first_name, last_name etc. using UpdateView?

Milano
  • 18,048
  • 37
  • 153
  • 353

2 Answers2

2

UpdateView is only made to handle one model with no relations. However, the wonderful django-extra-views library provides CBVs for models and inline relations.

class UserProfileInline(InlineFormSet):
    model = models.UserProfile
    form = UserProfileUpdateForm
    extra = 0
    def get_factory_kwargs(self):
        kwargs = super(UserProfileInline,self).get_factory_kwargs()
        kwargs.update({"min_num": 1})
        return kwargs

class UserCreate(CreateWithInlinesView):
    model=User
    inlines = [UserProfileInline]
    form_class = UserForm
    success_url = reverse('some-success-url')
    # REQUIRED - fields or exclude fields of User model
    template_name = 'your_app/user_profile_update.html'

Be sure to check out the documentation for information on the variables passed to your template and how to work with inline formsets.

Ian Price
  • 7,416
  • 2
  • 23
  • 34
0

You have to create second form for User as well. Then pass it to the same UpdateView as a second form_class.

Note*: you may need to override get and post methods for UpdateView. This SO answer might help.

Render both forms in one template under one <form> tag:

<form action="" method="post">
    {% csrf_token %}
    {{ first_form }}
    {{ second_form }}
</form>
Community
  • 1
  • 1
chem1st
  • 1,624
  • 1
  • 16
  • 22