Hey,
Just trying to implement a duplicate function for an object - a Product, which has a formset of ProductSuppliers. E.g. the ProductSupplier object has a foreign key to the Product (and to a Supplier).
I already have an ProductUpdateView implementation that manages the ProductSupplier formset well. Subclassing that ProductUpdateView, I’m implementing a ProductDuplicateView. Which is essentially the same thing - I just need to save the Product object with a different pk. Great but…
… but the inline formset still have a reference to the initial (to be duplicated) object. I cannot seem to find a good way to manage this.
Let’s consider:
class ProductUpdateView:
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = SupplierProdFormset(self.request.POST, instance=self.object)
if (form.is_valid() and formset.is_valid()):
return self.form_valid(form, formset)
else:
return self.form_invalid(form, formset)
I’ll obviously need to override this post method, something like that:
class ProductDuplicateView(ProductUpdateView):
def post(self, request, *args, **kwargs):
self.object = None # since the "old" object with some pk isn't the "new" one after duplication
form_class = self.get_form_class()
form = form_class(request.POST)
formset = SupplierProdFormset(self.request.POST) # not passing in instance=... because the new object has not yet been created
if (form.is_valid() and formset.is_valid()):
return self.form_valid(form, formset)
else:
return self.form_invalid(form, formset)
The above formset is NOT valid, because:
- request.POST still has the id of the original object for its foreign key. I’m unsure what it would expected (e.g. when creating a new object with inline formsets… guessing “None”?). But it has a value, that doesn’t match the current object (which is None) and so doesn’t validate
- I don’t have a new object yet to assign as the parent instance. E.g. if I do say tmp_obj = form.save(commit=False), that gives me a (uncommited) new object instance. But it still doesn’t have a pk… guess I should do that in form_valid()?
What should I do? Should I iterate on the request.POST values for the foreign_key field of each of the forms in the inline formest to update them to… (nothing? so that Django sees it as a new parent form, as in the CreateView?)? Feels hacky. There has to be a more natural way to manage this.
Or am I wrong to decide to see this “DuplicateView” as a variation of an UpdateView? Would it be easier to see it as a variation on a CreateView?