前回の続きで、Djangoについて学んでいきます。
今回もモデルについて勉強していきます。
Djangoの勉強内容は以下の本を参考にしています。
参考
Python Django3超入門 (日本語) 単行本 – 2020/6/13 掌田 津耶乃 (著)
コードは以前の記事を参考にしてください。
Djangoを勉強してみる(入門編)
Djangoを勉強してみる(入門編その2)
Djangoを勉強してみる_urlを学ぶ(入門編)
Djangoを勉強してみる_テンプレートを学ぶ(入門編)
Djangoを勉強してみる_テンプレートを学ぶ_その2(入門編)
Djangoを勉強してみる_フォームを学ぶ_その1(入門編)
Djangoを勉強してみる_フォームを学ぶ_その2(入門編)
Djangoを勉強してみる_フォームを学ぶ_その3(入門編)
Djangoを勉強してみる_モデルを学ぶ_その1(入門編)
Djangoを勉強してみる_モデルを学ぶ_その2(入門編)
Djangoを勉強してみる_モデルを学ぶ_その3(入門編)
Djangoを勉強してみる_モデルを学ぶ_その4(入門編)
Djangoを勉強してみる_モデルを学ぶ_その5(入門編)
Djangoを勉強してみる_モデルを学ぶ_その6(入門編)
今回の目的
前回はCRUDのDelete(削除)画面を作成しCRUDのすべての基本をやりました。
今回は作成したデータから必要なものを取り出す検索について勉強していこうと思います。
検索画面を作ってみる
Djangoでは検索する機能のことを「フィルター」と呼びます。
フィルターを簡単にできるメソッドがDjangoでは用意されています。
そのメソッドは以下のように定義します。
変数 = Model名.objects.filter(フィルターの内容)
検索するためには、次のような作業を行います。
・検索するデータを入力する
・検索されたデータが一覧で表示される
それではやっていきます。
まずは、検索のためのurlを作成します。
1.urls.pyを編集
ファイル:sample_app>hello>urls.py
コード:
from django.urls import path
from . import views
urlpatterns = [
path('',views.index, name='index'),
path('create/', views.create, name='create'),
path('edit/<int:num>',views.edit, name='edit'),
path('delete/<int:num>',views.delete, name='delete'),
path('find/',views.find, name='find'), #追加
]
いつもの書き方なので説明は省略します。
続いて、検索用のフォームを準備します。
2.forms.pyを編集
ファイル:sample_app>hello>forms.py
コード:
from django import forms
from .models import Friend
class FriendForm(forms.ModelForm):
class Meta:
model = Friend
fields = ['name', 'mail', 'age', 'gender', 'birthday']
#以下を追加---
class FindForm(forms.Form):
find = forms.CharField(label='Find', required=False)
検索用にテキストを入力するフォームを準備しました。
次は検索用のテンプレートを新規に準備します。
3.find.htmlを編集
ファイル:sample_app>hello>templates>hello>find.html
コード:
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css" integrity="sha384-r4NyP46KrjDleawBgD5tp8Y7UzmLA05oM1iAEQ17CSuDqnUK2+k9luXQOfXJCJ4I" crossorigin="anonymous">
<title>{{ title }}</title>
</head>
<body class = "container">
<h1>{{ title }}</h1>
<p>{{ msg | safe }}</p>
<form action="{% url 'find' id %}" method=post>
{% csrf_token %}
{{ form.as_p }}
<tr><th></th><td>
<input type="submit" value="検索" class="btn btn-primary"></td></tr>
</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>
次はfind関数を作成します。
4.views.pyを編集
ファイル:sample_app>hello>views.py
コード:
from .forms import FindForm #追加
def find(request):
if (request.method == 'POST'):
form = FindForm(request.POST)
find = request.POST['find']
data = Friend.objects.filter(name__contains=find)
msg = 'Result:' + str(data.count())
else:
msg = 'seardh words...'
form = FindForm()
data = Friend.objects.all()
paramas = {
'title': '検索画面',
'msg': msg,
'form': form,
'data': data,
}
return render(request, 'hello/find.html', paramas)
必要な部分だけコードを書いています。
find関数の中身は次のようになっています。
まずはお決まりの、リクエストのメソッドがPOSTの場合に処理します。
処理の中身は、FindFormにPOSTされたデータを入れてインスタンスを作成します。
次に検索文字をfind変数に代入して、データベースの「name」の中からその文字を含むデータを取り出してdata変数に代入します。
nameのあとの「__contains」はあいまい検索をする時に使うものです。
もし「__contains」を記載しない場合、nameで完全一致したものを検索します。
name以外で検索したい場合は、モデル(models.py)で定義した変数名をしてすることで実現できます。例えばメールアドレスで検索する場合は「mail」となります。
最後にデータの数をカウントしてmsg変数に代入してます。
もしPOSTが無い場合はすべてのデータを表示する処理をelseに書いています。
以上で設定が終わったので、動作確認してみます。
動作確認
python manage.py runserver
ブラウザで以下にアクセスします。
http://localhost:8000/hello/find検索画面が表示されます。

テキスト「2」を入力して検索ボタンをクリックします。

ちゃんと2が入っているデータだけが検索できました。
今回の目的である検索をすることができました。
次回からさらにデータベースを利用する方法ついて勉強していこうと思います。
補足
最後に補足として、検索の範囲を広げたい時の話しをします。
先ほどの検索で「name」や「mail」といった1つの項目でしか検索することができません。もし、すべてのデータから検索したい場合は別の書き方をする必要があります。
その場合の書き方が次になります。
変数 = モデル名.objectss.filter(Q(1つ目の検索条件) | (Q(2つ目の検索条件))
実際のコードを入れると次のようになります。
from django.db.models import Q #追加
def find(request):
if (request.method == 'POST'):
form = FindForm(request.POST)
find = request.POST['find']
data = Friend.objects.filter(Q(name__contains=find) | Q(mail__contains=find))
msg = 'Result:' + str(data.count())
else:
msg = 'seardh words...'
form = FindForm()
data = Friend.objects.all()
paramas = {
'title': '検索画面',
'msg': msg,
'form': form,
'data': data,
}
return render(request, 'hello/find.html', paramas)
補足は以上となります。
本日はここまでです。ありがとうございました。
P.S.
勉強を継続することが苦手ですか?
少し前からココナラというサービスで習慣化のテクニックについて教えるサービスを始めました。
もし、いつも3日坊主で終わってしまうという方や、ダイエットを続けたい、勉強したい、運動したいなど何か習慣化したいと思っている方がいましたら全力でサポートしますので、まずは覗いてみてください。
すでに何人かの方に実践してもらって効果が出ているという感想をいただいてます。

コメント