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

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


You need to get the User object and then add it to emails_for_help field. You can't add an object to ManyToManyField when creating an instance. Have a look at the doc.

class Set_user(FormView):    template_name="pkm_templates/set_up_user.html"    form_class = Set_User_Form    success_url = '/thanks/'    def form_valid(self, form):        org = form.cleaned_data.get('organization')        emails = form.cleaned_data.get("share_email_with")        users = User.objects.filter(email__in=emails)        instance = Setupuser.objects.create(organization=org)        for user in users:            instance.emails_for_help.add(user)        return redirect("/")

Another way of doing this is to use .set().

class Set_user(FormView):    template_name="pkm_templates/set_up_user.html"    form_class = Set_User_Form    success_url = '/thanks/'    def form_valid(self, form):        org = form.cleaned_data.get('organization')        emails = form.cleaned_data.get("share_email_with")        users = User.objects.filter(email__in=emails)        instance = Setupuser.objects.create(organization=org)        instance.emails_for_help.set(users)        return redirect("/")

Or you can simply use .add() to add arbitrary number of objects.

class Set_user(FormView):    template_name="pkm_templates/set_up_user.html"    form_class = Set_User_Form    success_url = '/thanks/'    def form_valid(self, form):        org = form.cleaned_data.get('organization')        emails = form.cleaned_data.get("share_email_with")        users = User.objects.filter(email__in=emails)        instance = Setupuser.objects.create(organization=org)        instance.emails_for_help.add(*users)        return redirect("/")


I tried all the above solutions and it doesn't work on Django 3.0 . So, I did my own research and came up with the solution.The solution is gonna be pretty simple. My answer is in general. Let us say there exists a form-field specialFieldName which is defined as a ManyToManyField in models.py .

Why did that error occur?

The options of this field which the user entered through the 'django form' are stored as a Queryset. In this scenario, we simply cannot assign this queryset to a ManyToManyField attribute during the creation of the object based on this queryset. This is the reason you are getting the above error.

So, we first create the object based on all the information we have got from the django-form, except the specialFieldName and then we use add() method to add all the elements of this queryset to the object we just created.

So, we need to iterate over this queryset.

 returnedQueryset = form.cleaned_data.get('specialFieldName')    dummyObject = ObjectModel.objects.create(..using all the info except specialFieldname..)    for member in returnedQueryset:        dummyObject.add(member)

Unfortunately, the loop doesn't iterate over all the members of the returnedQueryset (Read Why?). Thus, the above thing doesn't work. We gotta get a bit more advanced and use iterator() method instead.

for member in returnedQueryset.iterator():    dummyObject.add(member)

Now it works fine.

(P.S. This was my first answer on Stackoverflow. Gratitude for all my mentors ;-))


I was getting the same error Direct assignment to the forward side of a many-to-many set is prohibited. Use plan_options.set() instead, when upgrading from an older Django version to Django 2.2 LTS.

However when I used .set() I got SyntaxError: can't assign to function call.For me the issue was fixed by adding _set:

existing_plan.plan_options_set = [x.pk for x in old_plan.plan_options.all()]