Python 搜索 Django 多个属性

Python Django multiple attributes in search

所以我有这个搜索表单: [医生][专业][城市]

这是HTML中的表格:

          <form data-provide="validation" data-disable="true" class="input-glass mt-7" method='POST' action='annuaire/'>
            {% csrf_token %}
              <div class="row">
                <div class="col-md-4">
                  <div class="input-group">
                    <div class="input-group-prepend">
                      <span class="input-group-text"><i class="ti-search mt-1"></i></span>
                    </div>
                    <input type="text" class="form-control" placeholder="Doctor's Name" name="kw_name">
                  </div>
                </div>
                <div class="col-md-4">
                  <div class="input-group">
                    <div class="input-group-prepend">
                      <span class="input-group-text"><i class="ti-search mt-1"></i></span>
                    </div>
                      <select class="form-control" name="kw_specialty">
                        <option value="" disabled selected>Specialty</option>
                        {% for spec in specialties %}
                          <option>{{ spec }}</option>
                        {% endfor %}
                      </select>
                  </div>
                </div>

                <div class="col-md-4">
                  <div class="input-group">
                    <div class="input-group-prepend">
                      <span class="input-group-text"><i class="ti-search mt-1"></i></span>
                    </div>
                      <select class="form-control" name="kw_city">
                        <option value="" disabled selected>City</option>
                        {% for city in cities %}
                          <option>{{ city }}</option>
                        {% endfor %}
                      </select>
                  </div>
                </div>   
              </div>
              <div class="row mt-2">
                <div class="col-md-12">
                  <button class="btn btn-lg btn-block btn-outline-light" type="submit" name="search_btn">Search</button>
                </div>
              </div>
            </form>

在说我的view.py内容之前,我想先提一下我的问题:搜索表单有很多情况,用户不必填写所有三个过滤器。但是,如果他们将文本输入留空,则结果将是全部。我希望搜索功能在文本字段为空时忽略该文本字段(仅在其中包含值时才考虑它)。此外,如果 2 个下拉列表为 Null(或 None),则该函数会出错。不管怎样,我想要的结果是给出 3 种不同的选择,如果有人使用多个属性,它们都必须是真的,如果选择是空的,它应该被忽略。

这是我的 views.py 文件:

def search(request):
    val_name = request.POST.get('kw_name')
    val_city = request.POST.get('kw_city')
    val_specialty = request.POST.get('kw_specialty')
    if val_city is None:
        val_city = ''
    if val_specialty is None:
        val_specialty = ''

    if 'search_btn' in request.POST:
        if val_city is None:
            if val_name is not None:
                doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) | 
                                                Q(user__last_name__icontains=val_name) & 
                                                Q(specialty__title__icontains=val_specialty))
            else:
                doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) | 
                                                Q(user__last_name__icontains=val_name) & 
                                                Q(specialty__title__icontains=val_specialty))
        elif val_specialty is None:
            doctors = Doctor.objects.filter(Q(user__first_name__icontains=val_name) | 
                                            Q(user__last_name__icontains=val_name) & 
                                            Q(city__title__icontains=val_city))


    elif 'closest_btn' in request.POST:
        # deleted because not related to the problem.

    context = {
        'page_title': 'Résultats des médecins',
        'doctors': doctors,
    }
    return render(request, "dashboard/results.html", context)

感谢您的大力帮助!

PS: 我已经在视图中添加了一些 ifs 和 elses 来尝试解决问题,但它仍然不起作用。有时它会给我不满足任何搜索条件的结果。

我已经能够通过使用字典成功地使用用户过滤器,然后在 filter() 函数中解压它们。对于你的情况,我会尝试如下操作:

def search(request):
    val_name = request.POST.get('kw_name', '')
    filters = {
        'city__title__icontains': request.POST.get('kw_city'),
        'specialty__title__icontains': request.POST.get('kw_specialty')
    }
    filters = {k: v for k, v in filters.items() if v}
    q = Q(user__first_name__icontains=val_name) | Q(user__last_name__icontains=val_name)
    doctors = Doctor.objects.filter(q, **filters)

    context = {
        'page_title': 'Résultats des médecins',
        'doctors': doctors,
    }
    return render(request, "dashboard/results.html", context)