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("/")
EDIT
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 ;-))