Почему объединение двух или более наборов запросов не работает идеально с формами .ModelMultipleChoiceField? - PullRequest
0 голосов
/ 02 июня 2018

Привет, удивительные люди!

Я боролся с этим часами.У меня есть форма, которая имеет поле с именем 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() былидолжен работать, поскольку это всего лишь комбинация из двух наборов запросов одной модели.

Спасибо!

1 Ответ

0 голосов
/ 02 июня 2018

Они делают две разные вещи.Я не думаю, что вы действительно хотели профсоюз.Вы не хотите один и тот же результат дважды, если он появляется в обоих наборах.То, что вы хотите, это запрос или, который дает вам побитовый оператор.Он принимает оба фильтра и делает их такими, как если бы вы написали их как

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...