ユーザーが3つの検索フィールドの1つ、または3つの任意の組み合わせを検索できる比較的単純な検索フォームを作成しようとしています。結果は、指定された用語に基づいてクエリセットをフィルタリングする必要があります。これがsearch_form.htmlからの私のフォームです:
<form class="form-horizontal" action="/search/" method="get">
<legend>Generate a Quiz:</legend>
<div class="control-group">
<label class="control-label" for="q">Search term</label>
<div class="controls">
<input type="text" name="q" placeholder="Search term" autocomplete="on"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="yr">Year</label>
<div class="controls">
<input type="text" name="yr" placeholder="Year" autocomplete="on"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="ct">Category</label>
<div class="controls">
<input type="text" name="ct" placeholder="Category" autocomplete="on"/>
</div>
</div>
<div class="controls">
<button type="submit" class="btn btn-primary">Fetch »</button>
</div>
</form>
そして、これが私の見解です:
def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
yr = request.GET['yr']
ct = request.GET['ct']
if not ((q or yr) or ct):
error = True
else:
question_set = Uroquiz.objects.filter(question__icontains=q).filter(year=yr).filter(cat_icontains=ct)
paginator = Paginator(question_set, 1)
page = request.GET.get('page')
try:
question_set = paginator.page(page)
except PageNotAnInteger:
question_set = paginator.page(1)
except EmptyPage:
question_set = paginator.page(paginator.num_pages)
return render_to_response('search_results.html',
{'question': question_set, 'query': q, 'year': yr, 'ct': ct})
return render_to_response('search_form.html', {'error': error})
問題:
'q'だけをファイルしてこれを作成したところ、正常に機能しました。'yr'フィールドをフィルターにチェーンすると、フォームに年が入力されている限り、正常に機能します。年(私のデータベースの整数フィールド)が空の場合、基数10のint()に対してValueError無効なリテラルが発生します:''。
'ct'フィールドにチェーンして、すべてのフィールドを検索しようとすると、エラーが発生します:キーワード'cat_icontains'をフィールドに解決できません。フィルタを(cat = ct)に変更すると正常に機能しますが、データベースの「cat」フィールドで_icontainsを使用できるはずです。私は基本的な何かが欠けていると確信しています、どんな助けでもありがたいです。
更新:以下の回答に基づく現在のソリューションは、フィールドの任意の組み合わせで検索できるようにするものです。
def search(request):
q = request.GET.get('q')
yr = request.GET.get('yr', 0)
ct = request.GET.get('ct')
question_set = Uroquiz.objects.all()
if q:
if not (yr or ct):
question_set = Uroquiz.objects.filter(question__icontains=q)
if yr:
if not (q or ct):
question_set = Uroquiz.objects.filter(year=yr)
if ct:
if not (q or yr):
question_set = Uroquiz.objects.filter(cat__icontains=ct)
if (q and yr):
if not ct:
question_set = Uroquiz.objects.filter(question__icontains=q).filter(year=yr)
if (q and ct):
if not yr:
question_set = Uroquiz.objects.filter(question__icontains=q).filter(cat__icontains=ct)
if (yr and ct):
if not q:
question_set = Uroquiz.objects.filter(year=yr).filter(cat__icontains=ct)
if ((q and yr) and ct):
question_set = Uroquiz.objects.filter(question__icontains=q).filter(year=yr).filter(cat__icontains=ct)
if not ((q or yr) or ct):
return render_to_response('search_form.html')
paginator = Paginator(question_set, 1)
page = request.GET.get('page')
try:
question_set = paginator.page(page)
except PageNotAnInteger:
question_set = paginator.page(1)
except EmptyPage:
question_set = paginator.page(paginator.num_pages)
return render_to_response('search_results.html',
{'question': question_set, 'query': q, 'yr': yr, 'ct': ct})
これは、これを解決するための「忙しい」方法のようです。この検索結果を達成するためのより慣用的/Python的な方法はありますか?