首页 > 解决方案 > 尝试使用 ListView 进行搜索时出现错误:“无法使用无作为查询值”

问题描述

我有一个包含多个搜索字段的搜索表单。我希望能够通过为任何字段输入值来进行搜索,并且不应强制为所有搜索字段输入值:

我的代码如下:

models.py:
class Listings(models.Model):
relator = models.ForeignKey(Realtor, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
address = models.CharField(max_length=200)
city = models.CharField(max_length=100)
state = models.CharField(max_length=100)
zipcode = models.CharField(max_length=20)
description = models.TextField(blank=True)
price = models.IntegerField()
bedrooms = models.IntegerField()
bathrooms = models.DecimalField(max_digits=2, decimal_places=1)
garage = models.IntegerField(default=0)
sqft = models.IntegerField()
lot_size = models.DecimalField(max_digits=5, decimal_places=1)
photo_main = models.ImageField(upload_to='user_directory_path')
photo_1 = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)
photo_2 = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)
photo_3 = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)
photo_4 = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)
photo_5 = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)
photo_6 = models.ImageField(upload_to='photos/%Y/%m/%d', blank=True)
is_published = models.BooleanField(default=True)
list_date = models.DateTimeField(default=datetime.now, blank=True)


def __str__(self):
    return self.title
views.py:
class search(ListView):
template_name = 'listings/search.html'
queryset = Listings.objects.order_by('-list_date')
paginate_by = 6

# keywords
def get_queryset(self):
    description = self.request.GET.get('keywords')
    city = self.request.GET.get('city')
    state = self.request.GET.get('state')
    bedroom = self.request.GET.get('bedrooms')
    price = self.request.GET.get('price')
    object_list = self.queryset.filter(Q(description__icontains=description) |
                                       Q(city__iexact=city) |
                                       Q(state__iexact=state) |
                                       Q(bedrooms__lte=bedroom) |
                                       Q(price__lte=price))
    return object_list

def get_context_data(self, **kwargs):
    context = super(search, self).get_context_data(**kwargs)
    context['state_choices'] = state_choices
    context['price_choices'] = price_choices
    context['bedroom_choices'] = bedroom_choices
    return context

我的模板是:

          <form action="{% url 'search' %}">
        <!-- Form Row 1 -->
        <div class="form-row">
          <div class="col-md-4 mb-3">
            <label class="sr-only">Keywords</label>
            <input type="text" name="keywords" class="form-control" placeholder="Keyword (Pool, Garage, etc)" value="{{ values.keywords }}">
          </div>

          <div class="col-md-4 mb-3">
            <label class="sr-only">City</label>
            <input type="text" name="city" class="form-control" placeholder="City" value="{{ values.city }}">
          </div>

          <div class="col-md-4 mb-3">
            <label class="sr-only">State</label>
            <select name="state" class="form-control">
              <option selected="true" disabled="disabled">State (All)</option>
              {% for key,value in state_choices.items %}
                  <option value="{{ key }}" 
                  {% if key == values.state %}
                    selected
                  {% endif %}
                  >{{ value }}</option>
                {% endfor %}
            </select>
          </div>
        </div>
        <!-- Form Row 2 -->
        <div class="form-row">
          <div class="col-md-6 mb-3">
            <label class="sr-only">Bedrooms</label>
            <select name="bedrooms" class="form-control">
              <option selected="true" disabled="disabled">Bedrooms (Any)</option>
              {% for key,value in bedroom_choices.items %}
                  <option value="{{ key }}"
                  {% if key == values.bedrooms %}
                    selected
                  {% endif %}
                  >{{ value }}</option>
                {% endfor %}
            </select>
          </div>
          <div class="col-md-6 mb-3">
            <select name="price" class="form-control">
              <option selected="true" disabled="disabled">Max Price (All)</option>
              {% for key,value in price_choices.items %}
                  <option value="{{ key }}"
                  {% if key == values.price %}
                    selected
                  {% endif %}
                  >{{ value }}</option>
                {% endfor %}
            </select>
          </div>
        </div>
        <button class="btn btn-secondary btn-block mt-4" type="submit">Submit form</button>
      </form>

网址.py:

path('search', views.search, name='search')

我的错误是:

/listing/search 处的 ValueError

不能使用 None 作为查询值

请求方法:GET 请求 URL: http: //127.0.0.1 :8000/listing/search?keywords=&city=&price=500000 Django 版本:2.1.1 异常类型:ValueError 异常值:

不能使用 None 作为查询值

异常位置:C:\Users\LELA\Desktop\shopping\env\lib\site-packages\django\db\models\sql\query.py 在 build_lookup,第 1101 行 Python 可执行文件:C:\Users\LELA\Desktop\ shopping\env\Scripts\python.exe Python 版本:3.7.3 Python 路径:

['C:\Users\LELA\Desktop\shopping', 'C:\Users\LELA\Desktop\shopping\env\Scripts\python37.zip', 'C:\Users\LELA\Desktop\shopping\env\DLLs ', 'C:\Users\LELA\Desktop\shopping\env\lib', 'C:\Users\LELA\Desktop\shopping\env\Scripts', 'c:\users\lela\appdata\local\programs\ python\python37\Lib', 'c:\users\lela\appdata\local\programs\python\python37\DLLs', 'C:\Users\LELA\Desktop\shopping\env', 'C:\Users\LELA \Desktop\shopping\env\lib\site-packages']

服务器时间:2019 年 9 月 14 日星期六 20:25:53 +0000

标签: python-3.7django-2.2

解决方案


从我所看到的情况来看,我需要更多代码,我想问题出在此处:

.get_context_data(**kwargs)

由于您没有提供带有此参数的函数,因此它会尝试查询 None 然后引发异常,请尝试将静态数据(例如 '42069' 或 idk 之类的东西放在那里,看看它是否会改变任何东西


推荐阅读