为什么两个或多个查询集的联合不能与forms.ModelMultipleChoiceField完美配合?

时间:2018-06-01 22:57:46

标签: python django django-forms django-queryset

Hello Awesome People!

我挣扎了好几个小时。我的表单中有一个名为programs

的字段
programs = forms.ModelMultipleChoiceField(queryset=Program.objects.none(),
    required=False, widget=forms.CheckboxSelectMultiple())

我没有直接填写查询集参数,因为我在视图中有一些与它相关的操作,例如将默认programs与用户选择的programs组合在一起。

form = CourseForm(request.POST or None)
default_programs = Program.objects.filter(default=True)
all_programs = default_programs.union(user.programs.filter(default=False))

到目前为止,查询集也适用于union。我将查询集分配给表单域programs

form.fields['programs'].queryset = all_programs
if request.method == "POST":
    if form.is_valid():
        programs = form.cleaned_data.get("programs")
        ''' stuff '''
        course.programs.add(*programs)

这里有趣的是,即使我没有选择任何项目,programs总是收到所有的查询集,我之前尝试course.programs.clear(),但它不起作用,它仍然由所有人分配包含在queryset参数

中的程序

第2轮:1小时后

我将union更改为|,并且可以正常工作

all_programs = (default_programs | user.programs.filter(default=False)).distinct()

有谁知道为什么它不适用于union(),我不喜欢做我不理解的事情。
union()应该可以工作,因为它只是同一模型的2个查询集的组合。

谢谢!

1 个答案:

答案 0 :(得分:0)

他们做了两件不同的事情。我不认为你真的想要一个工会。如果它出现在两个集合中,您不希望两次获得相同的结果。你想要的是一个或查询,这是按位运算符给你的。它需要两个过滤器并使它们就像你把它们写成

一样

Program.objects.filter(Q(default=True) | Q(id__in=user.programs.values('id')))