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 %}