Как фильтровать в django пустые поля при использовании ChoiceField

У меня есть программа, в которой пользователи должны иметь возможность фильтровать различные типы технологий по их атрибутам. Мой вопрос заключается в том, как я буду фильтровать технологии, когда есть потенциальные конфликты и пустые значения в параметрах, которые я использую для фильтрации?

Forms.py:

class FilterDataForm(forms.ModelForm):
    ASSESSMENT = (('', ''),('Yes', 'Yes'),('No', 'No'),)

    q01_suitability_for_task_x = forms.ChoiceField(label='Is the technology suitable for x?',
    choices=ASSESSMENT, help_text='Please select yes or no', required=False,)
    q02_suitability_for_environment_y = forms.ChoiceField(label='Is the technology suitable for environment Y?',
    choices=ASSESSMENT, help_text='Please select yes or no', required=False)

В моей модели есть много полей, подобных приведенным выше.

views.py

class TechListView(ListView):
    model = MiningTech
def get_queryset(self):
        q1 = self.request.GET.get('q01_suitability_for_task_x', '')
        q2 = self.request.GET.get('q02_suitability_for_environment_y', '')

object_list = MiningTech.objects.filter(q01_suitability_for_task_x=q1).filter(
        q02_suitability_for_environment_y=q2)

return object_list

Сложность заключается в том, что не все записи в технологической базе данных будут содержать данные. Поэтому в моей текущей настройке бывают случаи, когда я отфильтровываю объекты, у которых есть один атрибут, но нет другого.

Например, если моя база данных имеет: pk1: q01_suitability_for_task_x=Yes; q02_suitability_for_environment_y=Yes; pk2: q01_suitability_for_task_x=Yes; q02_suitability_for_environment_y='';

В форме, если я не выбираю никакого значения для q01_suitability_for_task_x, и выбираю Yes для q02_suitability_for_environment_y, я не получаю ничего обратно в набор запросов, потому что нет пустых полей q01_suitability_for_task_x.

Любая помощь будет принята с благодарностью. Я также готов все перестроить, если потребуется.

Проблема в том, что ваш код self.request.GET.get(...) по умолчанию выдает пустую строку, если значение не найдено, поэтому ваша модель .filter() ищет совпадения, где строка имеет вид ''.

Я бы перестроил первую часть get_queryset(), чтобы создать словарь, который можно распаковать в ваш фильтр. Если значение не существует, то оно не добавляется в словарь фильтра:

filters = {}
q1 = self.request.GET.get('q01_suitability_for_task_x', None)
q2 = self.request.GET.get('q02_suitability_for_environment_y', None)

if q1 is not None:
   filters['q01_suitability_for_task_x'] = q1

... etc ...

object_list = MiningTech.objects.filter(**filters)

Если у вас много элементов q1, q2 и т.д., подумайте о том, чтобы поместить их в список, просмотреть и вставить в словарь, если .get(...) возвращает что-либо.

Вернуться на верх