Django formsets with attach

В Django есть отличная вещь – generic, которая содержит в себе такие конструкции как CreateView, UpdateView и т.д. Бывают ситуации, когда нам к форме модели необходимо добавить связанную сущность и записать это всё по одному сабмиту. В таком случае лучше всего прибгенуть к формсетам. Для начала необходимо описать сам формсет, который хотим использовать вместе с формой

from django.forms.models import inlineformset_factory
ImageFormSet = inlineformset_factory(Product, Image, extra=1, fields=['image'], can_delete=True)

и вот в самом UpdateView надо переопределить несколько методов:

class ProductUpdate(ProductMixin, UpdateView):
    def form_valid_formset(self, *args):
        for formset in args:
            if formset.is_valid():
                formset.save(commit=False)
                # Если нажали удалить у дочернего объекта
                for obj in formset.deleted_objects:
                    obj.delete()
                formset.save()
            else:
                return HttpResponseRedirect(self.get_success_url())

    def form_invalid_formset(self, *args):
        return self.render_to_response(self.get_context_data(**dict((a, a) for a in args)))

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.form_class
        form = self.get_form(form_class)
        return self.render_to_response(self.get_context_data(form=form, image_form=ImageFormSet(instance=self.object)))

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form = self.get_form(self.form_class)
        image_form = ImageFormSet(self.request.POST, self.request.FILES, instance=self.object)
        if form.is_valid():
            return self.form_valid_formset(image_form)
        else:
            return self.form_invalid(form) 

Вот так быстро можно сделать вложения в момент создания и редактирования

Прокрутить вверх