Search code examples
djangodjango-formsdjango-viewsformsets

UpdateView creates new objects instead of updating them


As the title says, when I try to use the UpdateView of a Parent Model with multiple Child Models to update them, instead of simply updating them, it creates new objects instead of updating them. I shouldn't have an issue with the form, models or anything because everything else is working, and I can edit the Parent Model, but the problem seems to be at the form_valid() method of my views.py. Here's the relevant code:

(Entrada = Parent Model, BalaMateriesPrimeres = Multiple Child Model)

class EntradaUpdateView(LoginRequiredMixin, UpdateView):
    model = Entrada
    fields = [...]
    template_name_suffix = '_update'

    def form_valid(self, form):
        self.object = self.get_object()
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        qs = BalaMateriesPrimeres.objects.filter(num_entrada=self.get_object())
        formsets = BalaMateriesPrimeresFormSet(self.request.POST, queryset=qs)

        if form.is_valid():
            form.save()
            if formsets.is_valid():
                instances = formsets.save(commit=False)
                for instance in instances:
                    instance.instance = self.object
                    instance.num_entrada = Entrada.objects.get(pk=self.object.id)
                    instance.save()
       return super(EntradaUpdateView, self).form_valid(form)

Edit: Things I've also tried:

  • This also duplicates the objects

    self.object = self.get_object()
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    qs = BalaMateriesPrimeres.objects.filter(num_entrada=self.get_object())
    formsets = BalaMateriesPrimeresFormSet(self.request.POST, queryset=qs)
    
    if form.is_valid():
        form.save()
        if formsets.is_valid():
            instances = formsets.save(commit=False)
            for instance in instances:
                instance.instance = self.object
                instance.num_entrada = Entrada.objects.get(pk=self.object.id)
                instance.save()
    
  • This just don't save anything:

    self.object = self.get_object()
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    qs = BalaMateriesPrimeres.objects.filter(num_entrada=self.get_object())
    formsets = BalaMateriesPrimeresFormSet(self.request.POST, queryset=qs)
    
    if form.is_valid():
        form.save()
        for formset in formsets:
            if formsets.is_valid():
                formset.instance = self.object
                formset.num_entrada = self.object.id
                print(formset.instance)
                formset.save()
    

    Seems like I'm missing a piece of the puzzle but I cannot figure out what


Solution

  • You've bypassed the functionality of the UpdateView by manually creating the form instance within that method. There is no reason to do that; you already have the form, passed as a parameter within that method. Remove the first three lines of the method.

    And you can also remove the is_valid() check; by definition, that method is only called if the form is already valid.