Django QuerySet API:如何加入iexact和icontains?

时间:2010-01-20 17:34:54

标签: django django-queryset

我有这个加入:

lawyers = Lawyer.objects.filter(last__iexact=last_name).filter(first__icontains=first_name)

This is the site

如果你尝试姓氏:阿巴斯和名字:Amr它告诉你阿巴斯有一个同学。

但是,如果你尝试使用名字,只会说数据库中没有名为amr的律师(显然有)。

如果我将(last__iexact=last_name)更改为(last__icontains=last_name),则将姓氏留空可以正常工作并找到amr。

但是last__icontains=last_name如果你搜索“collin”,你也会得到“collins”和“collingwood”,这不是我想要的。

你知道如何使用iexact并且如果它是空白的话也会被忽略吗?

由于

这是视图功能:

def search_form(request):
    if request.method == 'POST':
        search_form = SearchForm(request.POST)
        if search_form.is_valid():
            last_name = search_form.cleaned_data['last_name']
            first_name = search_form.cleaned_data['first_name']
            lawyers = Lawyer.objects.filter(last__iexact=last_name).filter(first__icontains=first_name)
            if len(lawyers)==0:
                form = SearchForm()
                return render_to_response('not_in_database.html', {'last': last_name, 'first': first_name, 'form': form})
            if len(lawyers)>1:
                form = SearchForm(initial={'last_name': last_name})
                return render_to_response('more_than_1_match.html', {'lawyers': lawyers, 'last': last_name, 'first': first_name, 'form': form}) 
            q_school = Lawyer.objects.filter(last__icontains=last_name).filter(first__icontains=first_name).values_list('school', flat=True)
            q_year = Lawyer.objects.filter(last__icontains=last_name).filter(first__icontains=first_name).values_list('year_graduated', flat=True)
            lawyers1 = Lawyer.objects.filter(school__iexact=q_school[0]).filter(year_graduated__icontains=q_year[0]).exclude(last__icontains=last_name)
            form = SearchForm()
            return render_to_response('search_results.html', {'lawyers': lawyers1, 'last': last_name, 'first': first_name, 'form': form})
    else:
        form = SearchForm()
        return render_to_response('search_form.html', {'form': form, })

1 个答案:

答案 0 :(得分:4)

您不必一次性构建QuerySet。

lawyers = Lawyer.objects.all()
if last_name:
    lawyers = lawyers.filter(last__iexact=last_name)
if first_name:
    lawyers = lawyers.filter(first__icontains=first_name)

Django不会在需要之前评估QuerySet(在这种情况下,len()调用会强制它进行评估),因此您可以在所有日子里保持堆叠过滤器,直到您准备好运行查询为止。

http://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated

此外,您不需要稍后创建新的QuerySet,您只需使用现有的QuerySet。

q_school = Lawyer.objects.filter(last__icontains=last_name).filter(first__icontains=first_name).values_list('school', flat=True)
q_year = Lawyer.objects.filter(last__icontains=last_name).filter(first__icontains=first_name).values_list('year_graduated', flat=True)

可以:

q_school = lawyers.values_list('school', flat=True)
q_year = lawyers.values_list('year_graduated', flat=True)