検索とフィルター
フィルターはたくさんあるデータの中から必要なものを絞り込むためのものです。
フィルターは以下のようなメソッドとして用意されています。
変数=<Model>.objects.filter(フィルターの内容)
urlpatternsの修正
今回はfindという検索用ページを新たに用意して下記のように定義します。
urlpatterns =[
..
path('find', views.find, name='find'),
]
forms.pyにFindFormを作成します。
hello/forms.py
from django import forms
from.models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = ['name','mail','gender','age','birthday']
class FindForm(forms.Form): #追加
find = forms.CharField(label='Find', required=False, \
widget=forms.TextInput(attrs={'class':'form-control'}))
find.htmlを作成します。
hello/templates/hello/find.html
{% load static %}
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>{{title}}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.css"
rel="stylesheet" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary">
{{title}}</h1>
<p>{{message|safe}}</p>
<form action="{% url 'find' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="click"
class="btn btn-primary">
</form>
<hr>
<table class="table">
<tr>
<th>id</th>
<th>name</th>
<th>mail</th>
</tr>
{% for item in data %}
<tr>
<th>{{item.id}}</th>
<td>{{item.name}}({{item.age}})</td>
<td>{{item.mail}}</td>
<tr>
{% endfor %}
</table>
</body>
</html>
views.pyにfind関数を作成します。
hello/views.py
from .forms import FindForm #この文を追記
def find(request):
if (request.method == 'POST'):
form = FindForm(request.POST)
find = request.POST['find']
data = Contact.objects.filter(name=find)
msg = 'Result: ' + str(data.count())
else:
msg = 'search words...'
form = FindForm()
data =Contact.objects.all()
params = {
'title': 'Hello',
'message': msg,
'form':form,
'data':data,
}
return render(request, 'hello/find.html', params)
webブラウザにてアクセスします。
nameで検索を行うことができる
LIKE検索
値を含む検索
項目名__contains=値
値で始まるものを検索
項目名__startswith=値
値で終わるものを検索
項目名__endswith=値
それでは、contains検索を実装してみましょう。
hello/views.py
def find(request):
if (request.method == 'POST'):
form = FindForm(request.POST)
find = request.POST['find']
data = Contact.objects.filter(name__contains=find) #追加
msg = 'Result: ' + str(data.count())
else:
msg = 'search words...'
form = FindForm()
data =Contact.objects.all()
params = {
'title': 'Hello',
'message': msg,
'form':form,
'data':data,
}
return render(request, 'hello/find.html', params)
webブラウザにてアクセスします。nameの一部分で検索をします。
大文字小文字を区別しない
大文字小文字を区別しない検索
項目名__iexact = 値
大文字小文字を区別しないLIKE検索
項目名__icontains=値
項目名__istartswith=値
項目名__iendswith=値
view.pyのfind関数を下記のように修正します。
hello/views.py
def find(request):
if (request.method == 'POST'):
form = FindForm(request.POST)
find = request.POST['find']
data = Contact.objects.filter(name__iexact=find) #修正
msg = 'Result: ' + str(data.count())
else:
msg = 'search words...'
form = FindForm()
data =Contact.objects.all()
params = {
'title': 'Hello',
'message': msg,
'form':form,
'data':data,
}
return render(request, 'hello/find.html', params)
webブラウザにてアクセスします。
数値の比較
値と等しい
項目名=値
値よりも大きい(>)
項目名__gt=値
値以上(=>)
項目名__gte=値
値よりも小さい
項目名__lt=値
値以下(<=)
項目名__lte=値
今回はageが〇〇歳以下で検索できるようにします。
view.pyのfind関数を下記のように修正します。
hello/views.py
def find(request):
if (request.method == 'POST'):
form = FindForm(request.POST)
find = request.POST['find']
data = Contact.objects.filter(age__lte=int(find)) #修正
msg = 'Result: ' + str(data.count())
else:
msg = 'search words...'
form = FindForm()
data =Contact.objects.all()
params = {
'title': 'Hello',
'message': msg,
'form':form,
'data':data,
}
return render(request, 'hello/find.html', params)
webブラウザにてアクセスします。
21歳以下で検索してみます。
〇歳以上、〇歳以下で検索する
両方の条件に合うものを探す場合、filter引数に2つの条件を書きます。
変数 = <モデル>.objects.filter(1つ目の条件, 2つ目の条件)
view.pyのfind関数を下記のように修正します。
hello/views.py
def find(request):
if (request.method == 'POST'):
form = FindForm(request.POST)
find = request.POST['find']
val = find.split()
data = Contact.objects.filter(age__gte=val[0], age__lte=val[1]) #☆
msg = 'search result: ' + str(data.count())
else:
msg = 'search words...'
form = FindForm()
data =Contact.objects.all()
params = {
'title': 'Hello',
'message': msg,
'form':form,
'data':data,
}
return render(request, 'hello/find.html', params)
webブラウザにてアクセスします。21歳以上40歳以下で検索してみます。
「21 40」のように間を半角スペースで区切ります。
OR検索
複数の項目でOR検索する場合は下記の形で指定します。
変数=<モデル>.objects.filter(@1つ目の条件 | @2つ目の条件)
view.pyのfind関数を下記のように修正します。nameとmailの2つを検索条件とします。
hello/views.py
from django.db.models import Q #この文を冒頭に追記
def find(request):
if (request.method == 'POST'):
msg = 'search result:'
form = FindForm(request.POST)
find = request.POST['find']
data = Contact.objects.filter\
(Q(name__contains=find)|Q(mail__contains=find)) #☆
else:
msg = 'search words...'
form = FindForm()
data =Contact.objects.all()
params = {
'title': 'Hello',
'message': msg,
'form':form,
'data':data,
}
return render(request, 'hello/find.html', params)
webブラウザにてアクセスします。
nameで検索できます。
mailでも検索できます。
リストを使って検索
データを全部探したい場合、リストを使った検索はを行う機能があります。
変数=<モデル>.objects.filter(項目名__in=リスト)
view.pyのfind関数を下記のように修正します。
hello/views.py
def find(request):
if (request.method == 'POST'):
msg = 'search result:'
form = FindForm(request.POST)
find = request.POST['find']
list = find.split()
data = Contact.objects.filter(name__in=list) #☆
else:
msg = 'search words...'
form = FindForm()
data =Contact.objects.all()
params = {
'title': 'Hello',
'message': msg,
'form':form,
'data':data,
}
return render(request, 'hello/find.html', params)
ではコードを見てみましょう。
下記では入力された値をリストに変換します。
find = request.POST['find']
list = find.split()
splitで半角スペースでテキストを分割しリストを作ります。
data = Contact.objects.filter(name__in=list)
webブラウザにてアクセスします。
ichiroとtaroを検索してみます。「ichiro taro」をスペースで区切って検索します。
この記事は役に立ちましたか?
もし参考になりましたら、下記のボタンで教えてください。
コメント