问题描述
我试图将ManyToMany-Relation渲染为ModelChoiceField而不是ModelMultipleChoiceField。所以我尝试了以下(简化):
I'm stuck trying to render a ManyToMany-Relation as a ModelChoiceField instead of a ModelMultipleChoiceField. So I tried the following (simplified):
models.py:
class Project(models.Model):
name = models.CharField(max_length=20, unique=True)
manager = models.ManyToManyField(User, related_name="manager_related")
forms.py:
class ProjectForm(forms.ModelForm):
manager = forms.ModelChoiceField(queryset=User.objects.all(),
empty_label='Choose Manager', required=False)
class Meta:
model = Project
fields = ['name', 'manager']
表单正确呈现,我可以从列表中选择已注册的用户。但是在提交表单后,我会得到一个 TypeError
,并显示消息'User'对象不可迭代
。我认为save()函数需要两个值来保存ManyToMany-Relation,但是ModelChoiceField只返回一个。我不知道如何解决这个问题...
The form renders correctly and I can select a registered user from the list. But after submitting the form, I'll get a TypeError
with the message 'User' object is not iterable
. I think that the save() function needs two values to save a ManyToMany-Relation but the ModelChoiceField returns only one. I don't know how to solve that...
推荐答案
Wtowers建议不行。为什么?请阅读一条:
After fiddling around I got an working solution. Wtowers proposal is not working. Why? Read that one: https://stackoverflow.com/a/13336492/2153744
所以我们必须自己处理一切。
So we have to handle everything on our own.
forms.py
# helper class: returning full_name instead of username
class UserModelChoiceField(forms.ModelChoiceField):
def label_from_instance(self, obj):
return obj.get_full_name()
class ProjectForm(forms.ModelForm):
manager = UserModelChoiceField(queryset=User.objects.all(), label='Manager', required=True)
class Meta:
model = Project
fields = ['name']
views.py
if request.method == 'POST':
form = ProjectForm(request.POST)
if form.is_valid():
# get cleaned data from form
prj_name = form.cleaned_data['name']
prj_manager = form.cleaned_data['manager'] # this is a User-object
# generate project and store it to db
prj = Project(name=prj_name)
prj.save()
# handling now m2m relation for manager
prj.manager.add(prj_manager)
return HttpResponseRedirect("/project/list")
else:
form = ProjectForm()
这篇关于使用ModelChoiceField替换ManyToMany-Relation的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!