Multiple models in UpdateView
Asked Answered
O

2

7

Is it possible to pass multiple models into the UpdateView?

Something like:

models = (FirstModel, SecondModel)
Oxbow answered 10/7, 2013 at 7:46 Comment(0)
R
11

Not via the models attribute for UpdateView.

But what you can do is either utilize extra_context or override the get_context_data() and add the models there.

An example of one such override would be:

class TaffyUpdateView(UpdateView):

    def get_context_data(self, **kwargs):
        context = super(TaffyUpdateView, self).get_context_data(**kwargs)
        context['second_model'] = SecondModel.objects.get(id=1) #whatever you would like
        return context
Removal answered 10/7, 2013 at 7:56 Comment(3)
I need to update those two models, not just pass them to the template.Oxbow
Of course this was the minimal example on how you'd do it. Create a form and add it via get_context_data() and have it sent back.Removal
@dimazubrik don't ask / expect tailored solutions, we won't take the fun out of it for you :) what Limelight suggested is actually a viable approach worth investigating, been doing this for the last 6 months or so at work :)Bey
P
0

Here is a solution for UpdateView with two models and one form with filling initial values and returning error messages. With comments and explanations for beginners.

Suppose we need to update an user account and add additional field (profile e.g.) from other model to edit.

models.py:

class Additional_data(models.Model):
    my_data = models.CharField(max_length=30)
    data_owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='additional_data')

forms.py:

class UserUpdateForm(forms.ModelForm):
    # our additional field my_data_field
    my_data_field = forms.CharField(max_length=30)
    class Meta:
        model = User
        # field for user model, suppose we edit two of them
        fields = ['username', 'email']

views.py:

class UserUpdateView(UpdateView):
    template_name = 'my_account.html'
    form_class = UserUpdateForm

    def get_object(self):
        # let know UpdateView what exactly user is updating
        return self.request.user

    def get_context_data(self, **kwargs):
        # UpdateView use this function to get data for passing in template, reimlement it
        context = super().get_context_data(**kwargs)
        user = self.request.user
        # here context has all data we need, except initial value for our additional field, so add it    
        # here we have direct access to initial field, actually we can here any value we need, 
        # in our case it is first object of additional data model
        context['form'].fields["my_data_field"].initial = user.additional_data.first().my_data
        return context

    def form_valid(self, form):
        # UpdateView use this function to save form in DB after validation
        user = form.save()
        # here we saved user data but not our additional field, so save it "manualy"
        additional_data = user.additional_data.first() # first object again
        additional_data.my_data = form.cleaned_data['my_data_field']
        additional_data.save()
        # redirect after successful saving, to "home" for example
        return HttpResponseRedirect(reverse('home'))
Paulapauldron answered 27/5 at 9:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.