/ / Django Many To Many Gerenciamento com formset inline - python, django, django-orm, inline-formset

Django Many To Many Gerenciamento com formset inline - python, django, django-orm, inline-formset

Eu não consigo encontrar um Boa maneira de resolver esta situação. Eu tenho dois modelos Office e People com muitos para muitos relacionamento através de um Contact modelo com campos adicionais.

Agora no meu views (CreateView e UpdateView), estou usando o formset in-line para gerenciar o relacionamento.

Meu problema aqui é com UpdateView, como atualizo o relacionamento muitos para muitos? Eu posso adicionar novos itens. Mas como excluir os existentes? O formset gera uma caixa de seleção DELETE mas eu me perco no código. Como usá-lo?

Uma maneira seria excluir todas as linhas correspondentes no modelo de passagem e recria as novas com dados enviados do formulário, mas acredito que deveria haver uma maneira mais eficiente de fazer isso.

Alguém pode ajudar?

Aqui está o meu código atual:

def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = OfficeContactInline(request.POST, instance=self.object)
if form.is_valid() and formset.is_valid():
self.object = form.save()
contacts = formset.save(commit=False)
for contact in contacts:
contact.office = self.object
contact.save()
formset.save_m2m()
return HttpResponseRedirect(self.get_success_url())
else:
return render(request, self.template_name, self.get_context_data(form=form, formset=formset))

Respostas:

0 para resposta № 1

Eu finalmente encontrei uma solução para o meu problema. Existe realmente uma mudança no comportamento com o Django 1.7: formset.save(commit=False) não exclui mais itens excluídos (caixa de seleção marcada). Você, portanto, tem que usar formset.deleted_objects para fazer isso: código de trabalho abaixo

def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = OfficeContactInline(request.POST, instance=self.object)
if form.is_valid() and formset.is_valid():
self.object = form.save()
contacts = formset.save(commit=False)
# New with Django 1.7
for del_contact in formset.deleted_objects:
del_contact.delete()

for contact in contacts:
contact.office = self.object
contact.save()
formset.save_m2m()
return HttpResponseRedirect(self.get_success_url())
else:
return render(request, self.template_name, self.get_context_data(form=form, formset=formset))

Isso está documentado aqui: https://docs.djangoproject.com/en/1.7/topics/forms/formsets/#django.forms.formsets.BaseFormSet.can_delete