Python 禁止直接分配给多对多集合的前端。改用 emails_for_help.set()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/50015204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Direct assignment to the forward side of a many-to-many set is prohibited. Use emails_for_help.set() instead
提问by conf
I am new to Django and didn't find any reference regarding this issue. I am getting this error when i use many to many field in Django model (models.py
). I guess the issue is assigning m2m field in view(views.py
) from form(forms.py
).
我是 Django 的新手,没有找到有关此问题的任何参考资料。当我在 Django 模型 ( models.py
) 中使用多对多字段时出现此错误。我猜问题是views.py
从 form( forms.py
) 中在 view( ) 中分配 m2m 字段。
How to assign m2m field in view?
(Django version 2.0
, python - 3.5
)
如何在视图中分配 m2m 字段?( Django version 2.0
, python - 3.5
)
models.py
模型.py
class User(AbstractUser):
username=models.CharField(max_length=20)
email = models.EmailField(_('email address'), unique=True)
class Setupuser(models.Model):
organization=models.CharField(max_length=200,blank=False,null=True)
emails_for_help = models.ManyToManyField(User)
views.py
视图.py
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("emails_for_help")
instance = Setupuser(organization=org,emails_for_help=emails)
instance.save()
return redirect("/")
forms.py
表格.py
class Set_User_Form(ModelForm):
emails_for_help = forms.ModelMultipleChoiceField(
queryset=User.objects.all(),
widget=forms.CheckboxSelectMultiple
)
class Meta:
model = Setupuser
fields = ["organization","emails_for_help"]
回答by MD. Khairul Basar
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.
您需要获取User
对象,然后将其添加到emails_for_help
字段中。ManyToManyField
创建实例时不能添加对象。看看文档。
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()
.
另一种方法是使用.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.
或者您可以简单地使用.add()
添加任意数量的对象。
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("/")
回答by Animesh Kumar
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
.
我尝试了上述所有解决方案,但在 Django 3.0 上不起作用。所以,我做了我自己的研究并提出了解决方案。解决方案将非常简单。我的回答是一般。假设存在一个specialFieldName
定义为 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.
用户通过“django 表单”输入的此字段的选项存储为Queryset。在这种情况下,我们根本无法ManyToManyField
在基于此查询集创建对象期间将此查询集分配给属性。这就是您收到上述错误的原因。
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.
因此,我们首先根据从 django-form 中获得的所有信息创建对象specialFieldName
,然后我们使用 add() 方法将这个查询集的所有元素添加到我们刚刚创建的对象中。
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.
不幸的是,循环不会遍历返回查询集的所有成员(阅读为什么?)。因此,上述事情不起作用。我们必须更高级一点,并改用 iterator() 方法。
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 ;-))
(PS 这是我在 Stackoverflow 上的第一个回答。感谢我所有的导师 ;-))