JSRB
JSRB

Reputation: 2623

Django fails to process ManyToMany form field within view to create and save new model instance

I have two Models with a ManyToMany relationship. In my view I want to process the user input of the MultipleChoicesField and assign the selected choices to the Poller object.

It raises the following error:

Direct assignment to the forward side of a many-to-many set is prohibited. Use poller_categories.set() instead.

Models.py

class Categories(models.Model):
    poller_category = models.CharField(max_length=30)
    poller_category_id = models.IntegerField(default=0)

    def __str__(self):
        return str(self.poller_category)


class Pollers(models.Model):

    [..]

    # Poller Category
    poller_categories = models.ManyToManyField(Categories)

    def __str__(self):
        return str(self.poller_id)

Forms.py

class PollersForm(forms.Form):

    [..]

    # Poller Tags
    poller_categories = forms.ModelMultipleChoiceField(queryset=Categories.objects.all())

views.py

def raise_poller(request):
        # if this is a POST request we need to process the form data
        if request.method == 'POST':

            # create a form instance and populate it with data from the request:
            form = PollersForm(request.POST)

            # check whether it's valid:
            if form.is_valid():
                # process the data in form.cleaned_data as required

                poller_nature = form.cleaned_data['poller_nature']
                poller_text = form.cleaned_data['poller_text']
                poller_choice_one = form.cleaned_data['poller_choice_one']
                poller_choice_two = form.cleaned_data['poller_choice_two']
                poller_categories = form.cleaned_data['poller_categories']

                # Get the user
                created_by = request.user

                # Save the poller to the database
                p = Pollers(poller_nature = poller_nature,
                            poller_text = poller_text,
                            poller_choice_one = poller_choice_one,
                            poller_choice_two = poller_choice_two,
                            poller_categories = poller_categories,    # here seems to be my issue?
                            created_by = created_by)
                p.save()

                # redirect to a new URL:
                return HttpResponseRedirect('/')

Upvotes: 1

Views: 91

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477641

You can not directly assign a value to the poller_categies. You should first save the Pollers object to the database, and then use p.poller_categories.set(…) to populate the many-to-many: relation

p = Pollers(
    poller_nature = poller_nature,
    poller_text = poller_text,
    poller_choice_one = poller_choice_one,
    poller_choice_two = poller_choice_two,
    # no poller_categories,
    created_by = created_by
)
p.save()
p.poller_categories.set(poller_categories)

The basic reason for this is likely that you need the primary key of both objects before you can link two items together, so at that moment there is not (yet) a record in the database for p.

Upvotes: 1

Related Questions