使用多选表单在 DJANGO 中过滤

Posted

技术标签:

【中文标题】使用多选表单在 DJANGO 中过滤【英文标题】:Filter in DJANGO using Multiple Select Form 【发布时间】:2020-10-12 14:51:21 【问题描述】:

我有一个单一的表单输入(见下文),用户可以在其中根据多个属性(例如名称、它拥有什么设备、它是否具有具有某些能力和材料功能的设备等)过滤创意工坊对象。

形式:

表单模板:

    <form method="get" action=".">
        <fieldset>
          <legend>WHAT ARE YOU LOOKING FOR?</legend>
            <div class="suggestion-wrap">
            <span>Workshop</span>
            <span>Equipment</span>
            <span>Materials</span>
            <span>Capabilities</span>
          </div>
            <div class="inner-form">
            <div class="input-field">
              <select multiple placeholder="Type to search..." name="name_contains" id="choices-text-preset-values" class="form-control">

                  % for Material in material_list %
                  <option> Material.material </option>
                  % endfor %

                  % for MachineType in machinetype_list %
                    <option> MachineType.machineType </option>
                    % endfor %

                  % for Capabilities in capabilities_list %
                  <option> Capabilities.capabilities </option>
                  % endfor %

                  % for Workshop in workshop_list %
                  <option> Workshop.workshop_name </option>
                  % endfor %

                  % for Equipment in equipment_list %
                  <option> Equipment.equipment_name </option>
                  % endfor %


              </select>
                <div class="select-dropdown"></div>

                <button class="btn-search" type="submit">
                <svg xmlns="http://www.w3.org/2000/svg"   viewBox="0 0 24 24">
                  <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
                </svg>
              </button>

            </div>
          </div>


        </fieldset>

        <!-- <button class="btn-submit" type="submit">search</button> -->


      </form>

如您所见,这是一个多选字段,其中包含来自每个可搜索类别的选项。它被设计成一个多合一的酒吧。对于这个例子(见上图),我希望能够展示所有拥有可以轧钢和铝的设备的车间。

当您按搜索时,URL 如下所示: http://127.0.0.1:8000/?name_contains=Mill&name_contains=Steel&name_contains=Aluminium

这是我迄今为止尝试过的: 视图.py:

def BootstrapFilterView(request):
    qs = Workshop.objects.all()

    name_contains_query = request.GET.get('name_contains')

    if is_valid_queryparam(name_contains_query):
        qs = Workshop.objects.filter(Q(workshop_name__icontains=name_contains_query)
                                 | Q(equipment__equipment_name__icontains=name_contains_query)
                                 , Q(equipment__equipment_materials__material__icontains=name_contains_query)
                                 , Q(equipment__equipment_capabilities__capabilities__icontains=name_contains_query)
                                 , Q(equipment__equipment_machineType__machineType__icontains=name_contains_query)
                                 ).distinct()


capabilities_list = Capabilities.objects.order_by('capabilities')
    machinetype_list = MachineType.objects.order_by('machineType')
    material_list = Material.objects.order_by('material')

    equipment_list = Equipment.objects.all()
    workshop_list = Workshop.objects.all()

    print(name_contains_query)
    return render(request, "bootstrap_form.html", 'capabilities_list': capabilities_list,
                                                   'material_list': material_list,
                                                   'machinetype_list': machinetype_list,
                                                   'equipment_list': equipment_list,
                                                   'workshop_list': workshop_list,
                                                   'queryset': qs
                                                   )

这个过滤器的目标是显示:

    如果添加了带有工作室名称的标签,则为工作室 具有特定属性的特定设备的所有车间

目前,我不知道如何传入输入的整个搜索标签列表。 使用这个网址: http://127.0.0.1:8000/?name_contains=Mill&name_contains=Steel&name_contains=Aluminium

过滤器仅使用最后一个标签,在本例中为铝。我怎样才能让它使用所有这些: 轧机、钢、铝

如果我可以创建一个新数组或列出所有输入的标签,我想我可以让它工作。我们将不胜感激。

【问题讨论】:

【参考方案1】:

来自 django QueryDict getlist() docs

QueryDict.getlist(key, default=None)

返回带有请求键的数据列表。返回一个空 如果键不存在且未提供默认值,则列出。 除非提供默认值,否则保证返回一个列表 不是列表。

request.GET.getlist('name_contains')

【讨论】:

我如何使用它进行过滤? 这似乎有效:qs = Workshop.objects.filter(Q(workshop_name__in=search_items) | Q(equipment__equipment_name__in=search_items)).distinct()

以上是关于使用多选表单在 DJANGO 中过滤的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 Django 中的表单上使用脆表单过滤器时收到“无效表单:脆”错误,但仅在一个 django 应用程序中而不是另一个?

Django ListView - 过滤和排序的表单

选择后多选上升

使用带有多选复选框的 Ajax 帖子过滤器获取帖子

在 Django 表单集中过滤对象

使用过滤器将表单提交给 django-admin 模型