【问题标题】:Filter multiple keywords过滤多个关键字
【发布时间】:2016-02-01 08:41:46
【问题描述】:

我正在尝试在我的网站上创建一个搜索优化器来过滤关键字,问题是有时人们可能想要搜索多个关键字。问题是默认情况下,如果他们输入“hello world”,它会搜索那个确切的短语,但是我希望它把它分开,以便搜索“hello”和“world”。到目前为止,我已将.split() 添加到关键字中,并且确实将其分开,但是它阻止了我在查询中使用__icontains。谁能建议最好的方法来做到这一点?干杯!

代码 -

def browse(request):

    business_industry = request.GET.get('business_industry', '')
    business_address_region = request.GET.get('business_address_region', '')
    employment_type = request.GET.get('employment_type', '')
    pay_rate = request.GET.get('pay_rate', '')
    keywords = request.GET.get('keywords', '').split()

    form = JobSearchForm(initial=request.GET)

    filters = Q(active_listing=True)

    if business_industry:
        filters &= Q(business_industry=business_industry)
    if business_address_region:
        filters &= Q(business_address_region=business_address_region)
    if employment_type:
        filters &= Q(employment_type=employment_type)
    if pay_rate:
        filters &= Q(pay_rate=pay_rate)
    if keywords:
        filters &= Q(job_description__icontains=keywords) | Q(job_title__icontains=keywords)

    job_listings = JobListing.objects.filter(filters).distinct().order_by('-listing_date')

    context_dict = {
        'joblistings': job_listings,
        'form': form
    }

    return render(request, 'browse.html', context_dict)

编辑: 我被要求解释为什么这篇文章是独一无二的,另一个问题是询问如何将他的查询与他的所有模型字段进行比较。这是询问如何从单个字段中过滤多个关键字。

【问题讨论】:

标签: python django


【解决方案1】:

你可以使用Reduce函数:

reduce(lambda x, y: x | y, [Q(name__icontains=word) for word in list])

更改此代码:

if keywords:
    filters &= Q(job_description__icontains=keywords) | Q(job_title__icontains=keywords)

收件人:

if keywords:
    fliters &= reduce(lambda x, y: x | y, [Q(job_description__icontains=word) for word in keywords]) | reduce(lambda x, y: x | y, [Q(job_title__icontains=word) for word in keywords])

您可以随意更改 lambda 定义。例如,如果您想查找包含所有关键字的列表,请将 lambda x, y: x | y 替换为 lambda x, y: x & y

编辑: 修改代码,因为有两个不必要的括号

【讨论】:

  • 这很完美!最初,我对这个答案感到厌烦,纯粹是因为我没有足够的能力来理解 reduce 函数,而且它看起来非常困难。尽管如此,我还是尝试了代码,它完美无瑕,令人印象深刻。谢谢!
  • 谢谢,reduce 是一个内置函数,你可以阅读它here
【解决方案2】:

您可以在keywords 上循环查询:

job_description_q = Q()
for keyword in keywords:
    job_description_q |= Q(job_description__icontains=keyword)
filters &= job_description_q 

jobtitle 也有类似的循环。

【讨论】:

  • 这有点解决了我的问题,而代码工作它确实有问题。它查找具有任何关键字的任何列表,我希望它找到具有所有关键字的列表。你知道如何为此修改它吗?
  • 您可以在循环中使用&= 而不是|=
【解决方案3】:

您可能需要为此使用迭代

keyword_filter = Q()
for keyword in keywords:
   keyword_filter|=Q(job_description__icontains=keyword) | Q(job_title__icontains=keyword)
filters &= keyword_filter

你可以看看这个类似的问题https://stackoverflow.com/a/5956422/2599266

【讨论】:

  • 这有点解决了我的问题,而代码工作它确实有问题。它查找具有任何关键字的任何列表,我希望它找到具有所有关键字的列表。你知道如何为此修改它吗?
【解决方案4】:
filters = {'active_listing':True}
q = Q()

if business_industry:
    filters['business_industry'] = business_industry
if business_address_region:
    filters['business_address_region'] = business_address_region
if employment_type:
    filters['employment_type'] = employment_type
if pay_rate:
    filters['pay_rate'] = pay_rate
if keywords:
    q = Q(job_description__icontains=keywords) | Q(job_title__icontains=keywords)

job_listings = JobListing.objects.filter(q, **filters).distinct().order_by('-listing_date')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-18
    • 2018-08-28
    • 2021-06-04
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    相关资源
    最近更新 更多