Home > Mobile >  Django ManyToMany .add() doesn't add the elements to the created object
Django ManyToMany .add() doesn't add the elements to the created object

Time:12-29

This is in my template:

 <form hx-post="{% url 'orders:create' %}">
    {% csrf_token %}
    {% for service in venue.services.all %}
            <input type="checkbox" name="services" value="{{ service.id }}"> {{ service.name }}<br>
    {% endfor %}
        <button
          hx-include="[name='id']"
          type="submit"
          >
          <input type="hidden" value="{{ venue.id }}" name="id">
          Submit
        </button>
  </form>

And this is the view:

class OrderCreateView(CreateView):
    model = Order
    form_class = OrderForm
    template_name = "orders/order_page.html"
    success_url = reverse_lazy("orders:success")

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["venues"] = Venue.objects.all()
        return context

    def form_valid(self, form):
        if self.request.htmx:
            # Get the IDs of the chosen services
            service_ids = self.request.POST.getlist('services')

            # Set the venue field of the form
            form.instance.venue = Venue.objects.get(id=self.request.POST.get("id"))

            # Save the form
            self.object = form.save()

            # Add the chosen services to the Order object
            for service_id in service_ids:
                service = Service.objects.get(id=service_id)
                self.object.chosen_services.add(service)

            return super().form_valid(form)


The problem is that the object is being created but only the line with form.instance.venue works, the part where the chosen_services are being added doesn't work, the object is created without any of them. The service_ids variable is populated with the information from the front end, it has the ids that i need, it just doesn't add them to the object.

This is models.py:

class Order(models.Model):
   venue = models.ForeignKey(Venue, on_delete=models.SET_NULL, null=True)
   chosen_services = models.ManyToManyField(Service, null=True, blank=True)

CodePudding user response:

Try this code

Here m2m field is already handled by form, you need to just set the value of the venue field with save() method of form

def form_valid(self, form):
    if self.request.htmx:
        # Get the IDs of the chosen services
        service_ids = self.request.POST.getlist('services')
        fm = form.save()
        # Set the venue field of the form
        fm.venue = Venue.objects.get(id=self.request.POST.get("id"))
        fm.save()
        
        return super().form_valid(form)

CodePudding user response:

The problem was that in forms.py i had this:

class OrderForm(forms.ModelForm):
    class Meta:
        model = Order
        fields = ["chosen_services"]

I deleted that and now it works!

  • Related