Django - Форма для редактирования объектов с отношением "один-ко-многим

У меня есть модель, содержащая список объектов переменной длины. Я хочу иметь возможность редактировать эту модель в форме и в той же форме редактировать каждый из связанных объектов в списке.

Я рассматривал наборы форм, которые могут быть способом обработки формы для нескольких объектов в списке, но из документации django и поиска в Интернете не очевидно, как я затем интегрирую это в форму родительского объекта. Каков наилучший практический подход к этому в Django?

Для этого вы можете использовать TabularInline или StackedInline.

#admin.py

from django.contrib import admin

class PostInlines(admin.TabularInline):
    model = Post
    fields = ["title"]
    extra = 1



@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    ...
    inlines = [PostInlines]

После этой категории (от отношения один ко многим) вы получите доступ к дочерним объектам, включая их обновление.

Наборы форм - именно то, что вам нужно

forms.py

from django.forms import inlineformset_factory
    
    
YourFormset = inlineformset_factory(
    ParentModel, 
    ChildrenModel, 
    fields="__all__", 
    extra=1,
)

views.py

class ParentModelUpdateView(UpdateView):
    model = ParentModel
    form_class = ParentForm
    success_url = reverse_lazy('{url}')
    template_name = '{template}'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['formset'] = YourFormset(instance=self.object)


    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        form = self.get_form(form_class)

        formset = YourFormset(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)

    def form_valid(self, form, formset):
        self.object = form.save()
        formset.instance = self.object
        formset.save()
        return HttpResponseRedirect(self.get_success_url())

    def form_invalid(self, form, formset):
        return render(
            self.request,
            self.template_name,
            super().get_context_data(
                form=form,
                formset=formset,
            ), status=400
        )

где-то в html

...
{{ formset.management_form }}
{% for form in formset.forms %}
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}
    ...
{% endfor %}
Вернуться на верх