【问题标题】:Django : Get queryset with filters over list (filled and/or empty)Django:通过列表过滤器获取查询集(填充和/或空)
【发布时间】:2019-03-23 09:35:27
【问题描述】:

我正在开发一个模块,借助用户定义的过滤器来显示对象。

查看.py 文件:

search_category = Document.objects.values_list('publication__category__name', flat=True).distinct()
kwargs['search_category'] = search_category

search_format = Document.objects.values_list('format', flat=True).distinct()
kwargs['search_format'] = search_format

search_language = Document.objects.values_list('language', flat=True).distinct()
kwargs['search_language'] = search_language

checkbox_category = self.request.GET.getlist('CategoryChoice')
checkbox_format = self.request.GET.getlist('FormatChoice')
checkbox_language = self.request.GET.getlist('LanguageChoice')
choice_title = self.request.GET.get('TitleChoice')

test_research = Document.objects\
            .filter(Q(publication__category__name__isnull=True) | Q(publication__category__name__in=checkbox_category))\
            .filter(Q(format__isnull=True) | Q(format__in=checkbox_format))\
            .filter(Q(language__isnull=True) | Q(language__in=checkbox_language))\
            .filter(Q(title__isnull=True) | Q(title__in=choice_title))

我的一个过滤器(语言)的模板文件:

<button class="btn btn-default btn-choice" type="button" data-toggle="collapse" data-target="#language"
                aria-expanded="false" aria-controls="language"><span
          class="glyphicon glyphicon-chevron-down"></span> {% trans 'Language' %}</button>
        <div class="row">
          <div class="col">
            <div class="collapse multi-collapse" id="language">
              <div class="card card-body card-choice">
                {% for language in search_language %}
                  <input type="checkbox" class="fakeRadio" name="LanguageChoice" value="{{ language }}">
                  {{ language }}<br>
                {% endfor %}
              </div>
            </div>
          </div>
        </div>

在我的网络应用程序中看起来像这样:

我可以选中一个或多个复选框,但也可以不选中某个特定条件的复选框。最后一个选项会产生问题,因为例如,如果我不检查 language,则生成的查询集是空的,不应该是因为它应该考虑其他过滤器。

示例:

Object 1 : Category = 'FOOD_CONTACT', Format = 'pdf', Language = 'FR', Title = 'This is my first title'
Object 2 : Category = 'FOOD_CONTACT', Format = 'epub', Language = 'EN', Title = 'This is my second title'
Object 3 : Category = 'OTHER', Format = 'pdf', Language = 'FR', Title = 'ZZ'

现在,如果我检查一下:

Category filter : ['FOOD CONTACT']
Format filter : []
Language filter : []
Title filter : 
It should return : Object 1, Object 2

Category filter : ['FOOD CONTACT']
Format filter : ['pdf']
Language filter : []
Title filter : 
It should return : Object 1

Category filter : []
Format filter : ['pdf']
Language filter : []
Title filter : 'Z'
It should return : Object 3

【问题讨论】:

  • 您是否从终端测试了这些单独的过滤器?
  • 你说的例子是category 吗?是的,我尝试了每一个(只是类别,只是格式,......)并且总是一个空的查询集
  • 那么Document.objects.filter(language__in=['EN'])这样的查询返回一个空结果?
  • 不,它会返回一些东西。 Document.objects.filter(language__in=['EN']).filter(format__in=['pdf']) 返回一些东西,但 Document.objects.filter(language__in=['EN']).filter(format__in=[ ]) 什么也没返回,在这种情况下,我想使用第一个过滤器获取所有对象。
  • 它与车间完全相同的过程。您可以购买带有过滤器的东西,它会根据特定的过滤器显示对象

标签: python django django-queryset django-q


【解决方案1】:

我认为解决方案是动态构建您的过滤器,只是不要包含用户没有要求的任何过滤器。

# default to all documents
test_research = Document.objects.all()

# if user entered any search criteria, add those filters
if category:
    test_research = test_research.filter(publication__category__name__in=category)

if format:
    test_research = test_research.filter(format__in=format)

if language:
    test_research = test_research.filter(language__in=language)

if title:
    test_research = test_research.filter(title__icontains=title)

【讨论】:

  • 我明天去办公室试试!你确定它会结合查询集吗?
  • 是的,它会将所有这些过滤器合并到一个查询集中。
  • 它似乎工作正常!我相信在一个查询集中这是可能的。
  • @Essex - 我需要澄清一下;查询是在 (Django) Listview 中调用的吗?如果是,变量是什么,例如category, format 等被提及?我在我的模型中使用了两个布尔字段,并希望在运行时应用 filter/s。目前我只是使用myModel.objects.filter(&lt;boolean_field1&gt;=False) 等。我正在尝试在 ListView 页面中构建两个 checkboxes,在检查 True 时将适用所需的过滤器。谢谢。
猜你喜欢
  • 2016-04-20
  • 2013-04-27
  • 2020-10-08
  • 1970-01-01
  • 2011-09-17
  • 2019-07-29
  • 1970-01-01
  • 2019-08-08
  • 2018-03-01
相关资源
最近更新 更多