多对多关系的 Select2 小部件
Posted
技术标签:
【中文标题】多对多关系的 Select2 小部件【英文标题】:Select2 widget for ManyToMany relationship 【发布时间】:2017-09-02 14:04:39 【问题描述】:我正在使用django-select2 小部件来获得更好的ManyToMany
小部件。视图看起来更好,我可以搜索和选择许多不同的用户。但是,当我保存模型时,允许的用户列表是空白的。我直接从视图和单元测试中尝试了这一点。我无法理解我做错了什么。
有什么想法吗?
我强烈怀疑有两个问题:一个是保存表单创建的模型,另一个是我如何设置data
字典值。
我的模特:
class ProjectCode(models.Model):
allowed_users = models.ManyToManyField(User, blank=True)
我的表格:
class ProjectCodeForm(forms.ModelForm):
class Meta:
model = ProjectCode
fields = '__all__'
widgets = 'allowed_users': Select2MultipleWidget(),
我的观点:
def create_code(request):
context =
if request.method == 'POST':
form = ProjectCodeForm(request.POST)
if form.is_valid():
new = form.save(commit=False)
new.save()
form = ProjectCodeForm()
context['form'] = form
return render(request, 'order_book/create_code.html', context)
我的测试:
def test_code_create_post_pass(self):
init = len(ProjectCode.objects.all())
data = 'allowed_users': [self.jdoe.pk, ],
response = self.client.post('/order_book/code/create/', data)
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Create a project code")
self.assertEqual(init + 1, len(ProjectCode.objects.all()))
self.assertEqual("jdoe", ProjectCode.objects.all()[0].display_allowed_users())
此测试失败:
======================================================================
FAIL: test_code_create_post_pass (order_book.tests.AuthorisedViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/path/tests.py", line 385, in test_code_create_post_pass
"jdoe", ProjectCode.objects.all()[0].display_allowed_users())
AssertionError: u'jdoe' != u''
- jdoe
+
【问题讨论】:
【参考方案1】:发个问题,继续玩pdb
,突然冒出一个想法……我把视图修改为:
def create_code(request):
context =
if request.method == 'POST':
form = ProjectCodeForm(request.POST)
if form.is_valid():
new = form.save(commit=False)
# I am doing "clever" things with the new object here,
# like setting a creator and created date/time…
new.save()
for usr in form.cleaned_data['allowed_users']: # ← This is NOT correct
new.allowed_users.add(usr) # ← Neither is this…
form = ProjectCodeForm()
context['form'] = form
return render(request, 'order_book/create_code.html', context)
我收到一条错误消息,提示 allowed_users
无法设置为 new
还没有主键。这导致我在保存对象后尝试设置数据。
请注意,测试data
是正确的,现在测试通过了。
或者,您可以read the freaking documentation 并使用正确的方法save_m2m()
:
def create_code(request):
context =
if request.method == 'POST':
form = ProjectCodeForm(request.POST)
if form.is_valid():
new = form.save(commit=False)
# I am doing "clever" things with the new object here,
# like setting a creator and created date/time…
new.save()
form.save_m2m() # ← This is CORRECT!
form = ProjectCodeForm()
context['form'] = form
return render(request, 'order_book/create_code.html', context)
【讨论】:
以上是关于多对多关系的 Select2 小部件的主要内容,如果未能解决你的问题,请参考以下文章