/ / Gestion de Django Many To Many avec formset en ligne - python, django, django-orm, inline-formset

Gestion Django Many To Many avec formset en ligne - python, django, django-orm, inline-formset

Je n'arrive pas à trouver un bien façon de résoudre cette situation. J'ai deux modèles Office et People avec plusieurs à plusieurs relation à travers un Contact modèle avec des champs supplémentaires.

Maintenant dans mon views (CreateView et UpdateView), j’utilise des formulaires en ligne pour gérer la relation.

Mon problème ici est avec UpdateView, comment mettre à jour la relation plusieurs à plusieurs? Je peux ajouter de nouveaux articles. Mais comment supprimer les existants? Le formset génère une case à cocher DELETE mais je me perds dans le code. Comment l'utiliser?

Une solution pourrait consister à supprimer toutes les lignes correspondantes du modèle intégral et à en recréer de nouvelles avec les données soumises à partir du formulaire, mais j'estime qu'il devrait exister un moyen plus efficace de le faire.

Quelqu'un peut aider?

Voici mon code actuel:

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))

Réponses:

0 pour la réponse № 1

J'ai finalement trouvé une solution à mon problème. Il y a en fait un changement de comportement avec Django 1.7: formset.save(commit=False) ne supprime plus les éléments supprimés (case à cocher cochée). Vous devez donc utiliser formset.deleted_objects le faire: code de travail ci-dessous

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))

Ceci est documenté ici: https://docs.djangoproject.com/en/1.7/topics/forms/formsets/#django.forms.formsets.BaseFormSet.can_delete