Обновить набор запросов фильтра выбора модели на основе значения другого фильтра - PullRequest
0 голосов
/ 23 января 2020

Я знаю, что мы можем изменить фильтр django в его методе init, и мы можем определить пользовательские функции фильтра для фильтрации набора запросов.

У меня есть выбор модели фильтр , который выбирает города из базы данных. Города содержат разные значения, например: Ахен, Ахен (Крайс) и др. c.

self.filters["city"] = ModelMultipleChoiceFilter(
            queryset=City.objects.exclude(name__contains="Kreis").order_by("name")
        )

У меня есть Булев фильтр с именем include_kreis

self.filters["include_kreis"] = BooleanFilter(
            field_name="city", widget=forms.CheckboxInput, method=self.kreis_custom_filter, label="Include Kreis"
        )

Как вы видите, изначально я исключил значения Kreis, и флажок снят.

Моя Пользовательская функция для фильтра include_kreis:

def kreis_custom_filter(self, queryset, name, value):
    if value == False:
        return queryset.exclude(city__name__contains="Kreis")
    else:
        return queryset.all()

Я добавляю города с Kreis в его имени для набора запросов на основе значения фильтра Bool.

Мне также нужно изменить значения в фильтре выбора модели City.

Примерно так:

self.filters["city"].queryset = City.objects.all().order_by("name")

Я пытался записать приведенную выше строку в пользовательской функции фильтра "include_kreis" в операторе else, но раскрывающийся список во внешнем интерфейсе не обновите значения.

НЕПРАВИЛЬНАЯ ПОПЫТКА:

def kreis_custom_filter(self, queryset, name, value):
    if value == False:
        return queryset.exclude(city__name__contains="Kreis")
    else:
        self.filters["city"].queryset = City.objects.all().order_by("name")
        return queryset.all()

Для этого можно отправить запрос ajax и снова заполнить раскрывающийся список, но неэффективно, так как у меня есть другие фильтры и javascript обработчики событий, так что * 10 56 * путь - это то, чего я не могу go.

Есть ли способ обновить набор запросов фильтра ModelChoice, который у меня есть в пользовательской функции фильтра или DJANGO не позволяет это сделать?

Также, если есть возможность добавить оператор if в init и проверьте текущее значение фильтра bool, а затем: определите фильтр с различными наборами запросов, что также является приемлемым.

Что-то вроде в init :

def __init__(self, *args, result_type=None, **kwargs):
    super(Evaluation_filter, self).__init__(*args, **kwargs)
    self.filters["include_kreis"] = BooleanFilter(
        field_name="city", widget=forms.CheckboxInput, method=self.kreis_custom_filter, label="Include Kreis"
    )
    if value of bool filter == on:
      self.filters["city"] = ModelMultipleChoiceFilter(
         queryset=City.objects.all().order_by("name")
      )

    else:
      self.filters["city"] = ModelMultipleChoiceFilter(
         queryset=City.objects.exclude(name__contains="Kreis").order_by("name")
      )

1 Ответ

0 голосов
/ 23 января 2020

Хорошо, так что я нашел решение:

Я могу добавить оператор if в методе init на основе на текущем запросе. Я заметил, что в * args отправляется весь запрос.

Решение:

def __init__(self, *args, result_type=None, **kwargs):
    super(Evaluation_filter, self).__init__(*args, **kwargs)
    self.filters["include_kreis"] = BooleanFilter(
        field_name="city", widget=forms.CheckboxInput, method=self.kreis_custom_filter, label="Include Kreis"
    )
    #evaluate if the checkbox is checked
    if args[0] and args[0].get("include_kreis"):
        city_queryset = City.objects.all().order_by("name")
    else:
        city_queryset = City.objects.exclude(name__contains="Kreis").order_by("name")

    self.filters["city"] = ModelMultipleChoiceFilter(queryset=city_queryset)

args[0] - это запрос в виде словаря.

Тогда мне нужно получить текущий значение include_kreis из этого.

Поскольку это логический фильтр, он будет заполнен в запросе только в том случае, если он отмечен / выбран , поэтому я использую args[0].get()

Затем, основываясь на операторе if, я могу заполнить значения для раскрывающегося списка городов.

Если установлен флажок , включить все города В противном случае исключить 'Kreis'

...