针对ManyToMany关系的Select2小部件

时间:2017-04-07 08:55:38

标签: python django django-forms jquery-select2

我正在使用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 个答案:

答案 0 :(得分:0)

发布问题,继续玩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)