不区分大小写的查询,支持多个搜索词

时间:2010-07-09 13:57:09

标签: python django case-sensitive

我正在尝试执行不区分大小写的查询。我通常会使用__icontains,但由于它不支持.split()方法,我坚持使用__in代替:

def search(request):
    query = request.GET.get('q', '')
    query = query.lower()
    product_results = []
    category_results = []
    if query:
        product_results =  Product.objects.filter(Q(title__in=query.split())|
                                                   Q(brand__in=query.split())|
                                                   Q(description__in=query).split())
        category_results = Category.objects.filter(title__in=query.split())

我的问题是对象字段通常首字母大写,因此全小写查询总是返回负数。

无论如何?

2 个答案:

答案 0 :(得分:1)

我已经通过使用exec来使用icontains而不是in来从字符串生成代码来解决这个问题。我承认,它很草率而且不优雅,应该进行审计以确保安全性,但它有效。

查看未经测试的/伪代码:

query = "product_results =  Product.objects.filter("
for word in words:
    query += "Q(title__icontains(word))|"
    query += "Q(brand__icontains(word))|"
    query += "Q(description__icontains(word))|"
query = query[:-1] # remove the trailing |
query += ")"
exec("product_results = "+query)

同样,这可能是不可取的,而且我确信有更好的方法可以做到这一点,但这让我陷入困境,所以我想我会分享。另请注意,我不再使用此代码,因为我已切换到sqlalchemy,这使得这些类型的动态查询更容易,因为它的“或”对象接受列表。

答案 1 :(得分:1)

感谢分享,我写了这个快速的黑客,根本不优雅....

def search(request):
    query = request.GET.get('q', '')
    query = query.split()
    product_results = []
    category_results = []
    if query:
        for x in query:
            product_results.extend(Product.objects.filter(Q(title__icontains=x)|
                                                       Q(brand__icontains=x)|
                                                       Q(description__icontains=x)))
            category_results.extend(Category.objects.filter(title__icontains=x))
    query = request.GET.get('q', '')
    product_results = list(set(product_results))
    category_results = list(set(category_results))
    return render_to_response('search_results.html', {'query': query,
                                                      'product_results': product_results,
                                                      'category_results': category_results})