'UpdateView with a ModelForm as form_class'-issue

django, django-class-based-views, django-forms

Solution

Having your view and model form correspond to different models seems a bad idea to me.

I would set `model = User` in your `EmailView`, then override `get_object` so that it returns the user corresponding to the given profile id.

Problem

The code I would like to get is for a page that has a simple form of one field to change a user's email address using an `UpdateView`. Sounds simple, but the difficulty is that I want the URL mapping `url(r'email/(?P<pk>\d+)/$', EmailView.as_view(),)` not to use the `id` of the Model used in my ModelForm (`User`) but the `id` of another Model (`Profile`). The `id` of a `Profile` instance of a specific user can be called as follows inside a view: `self.user.get_profile().id`. I am using the `Profile` model of the reusable app userena if you are wondering. A (afaik not optimally implemented ¹) feature of an `UpdateView` is that if you want to use your own ModelForm instead of letting the `UpdateView` derive a form from a Model you need to(otherwise produces an Error) define either `model`, `queryset` or `get_queryset`. So for my `EmailView` case I did the following: forms.py ``` class EmailModelForm(forms.ModelForm): class Meta: model = User fields = ( "email", ) def save(self, *args, **kwargs): print self.instance # returns <Profile: Billy Bob's Profile> instead of <User: Billy Bob> !!! return super(EmailModelForm, self).save(*args, **kwargs) ``` views.py ``` class EmailView(UpdateView): model = Profile # Note that this is not the Model used in EmailModelForm! form_class = EmailModelForm template_name = 'email.html' success_url = '/succes/' ``` I then went to `/email/2/`. That is the email form of the `user` that has a `profile` with `id` `2`. If I would run a debugger inside `EmailView` I get this: ``` >>> self.user.id 1 >>> profile = self.user.get_profile() >>> profile.id 2 ``` So far so good. But when I submit the form it won't save. I could overwrite the `save` method in the `EmailModelForm` but I'd rather override something in my `EmailView`. How can I do that? ¹ Because `UpdateView` could just derive the model class from the ModelForm passed to the `form_class` attribute in case it is a ModelForm.

Original source

Related problems