Как фильтровать в 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(...)
возвращает что-либо.