What are the steps to make a ModelForm work with a ManyToMany relationship with an intermediary model in Django?

前端 未结 5 1447
借酒劲吻你
借酒劲吻你 2020-12-23 11:46
  • I have a Client and Groupe Model.
  • A Client can be part of multiple groups.
  • Clients that are part of a gr
5条回答
  •  攒了一身酷
    2020-12-23 12:16

    If you use the save method right now, Django will try to save using the manager (which Django doesn't allow). Unfortunately, the behavior you want is a little bit trickier than what ModelForm does by default. What you need to do is create a formset.

    First of all, you will need to change the options of your ClientForm so that it doesn't display the groupes attribute.

    class ClientForm(ModelForm):
        class Meta:
            model = Client
            exclude = ('groupes',)
    

    Next, you must change the view to display the formset:

    from django.forms.models import inlineformset_factory
    
    def modifier(request, id):
        client = Client.objects.get(id=id)    
        form = ClientForm(instance = client)
        # Create the formset class
        GroupeFormset = inlineformset_factory(Client, Groupe)
        # Create the formset
        formset = GroupeFormset(instance = client)
    
        dict = {
            "form": form
            , "formset" : formset
            , "instance" : client
        }
    
        if request.method == "POST":
            form = ClientForm(request.POST, instance = client)
            formset = GroupeFormset(request.POST, instance = client)
    
            if form.is_valid() and formset.is_valid():
                client_mod = form.save()
                formset.save()
    
                id = client_mod.id
                return HttpResponseRedirect(
                    "/client/%(id)s/?err=success" % {"id" : id}
                )
            else:
                return HttpResponseRedirect(
                    "/client/%(id)s/?err=warning" % {"id" : id}
                )
    
        return render_to_response(
            "client/modifier.html"
            , dict
            , context_instance=RequestContext(request)
        )
    

    And obviously, you must also tweak your template to render the formset.

    If you need any other advice on formsets, see these articles:

    Model formsets
    Formsets

提交回复
热议问题