Django(自分のメモ用)
render関数
テンプレートはファイルパス
指定したテンプレートを読み込んでレンダリングして返す
render(<<Httprequest>>, テンプレート)
テンプレに値を渡す
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<p>{{msg}}</p>
</body>
</html>
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
params = {"title": "Hello/Index", "msg": "これはサンプルで作ったページです"}
return render(request, "hello/index.html", params)
複数のページ移動
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<p>{{msg}}</p>
<a href="{% url goto %}">{{goto}}</a>
</body>
</html>
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
params = {
"title": "Hello/Index",
"msg": "これはサンプルで作ったページです",
"goto": "next",
}
return render(request, "hello/index.html", params)
def next(request):
params = {
"title": "Hello/Next",
"msg": "これはもう一つのページです",
"goto": "index",
}
return render(request, "hello/index.html", params)
from django.urls import path
from . import views
# http://○○○/helloの後に続くアドレスを指定する
urlpatterns = [
path("", views.index, name="index"),
path("next", views.next, name="next"),
]
<a href="{% url 名前 %}">{{goto}}</a>
静的ファイルの利用
staticフォルダの利用
body{
color: gray;
font-size: 16pt;
}
h1{
color: blue;
opacity: 0.2;
font-size: 36pt;
margin-top: 20px;
margin-bottom: 0px;
text-align: right;
}
p{
margin: 10px;
}
a{
color: blue;
text-decoration: none;
}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}">
</head>
<body>
<h1>{{title}}</h1>
<p>{{msg}}</p>
<a href="{% url goto %}">{{goto}}</a>
</body>
</html>
Bootstrapの利用
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5">{{msg}}</p>
<p class="h6"><a href="{% url goto %}">{{goto}}</a></p>
</body>
</html>
表示画面
Bootstrap
class | 備考 |
---|---|
h数字 | テキストの大きさ(h1~h6) |
display-数字 | 大きく目立つタイトルなどのフォントとサイズの設定(1~6) |
text-名前 | テキストカラーの設定 |
m場所-数字 | マージンの指定。場所はt,b,l,r,x,yで数字は1~5とauto |
p場所-数字 | パディングを指定するもの。マージンと同様に使用 |
フォームで送信
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5">{{msg}}</p>
<form action="{% url 'form' %}" method="post">
{% csrf_token %}
<label for="msg" class="form-label">message: </label>
<input type="text" id="msg" name="msg" class="form-control">
<input type="submit" value="click" class="btn btn-primary">
</form>
</body>
</html>
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def index(request):
params = {"title": "hello/index", "msg": "お名前は?"}
return render(request, "hello/index.html", params)
def form(request):
msg = request.POST["msg"]
params = {
"title": "Hello/Form",
"msg": f"こんにちは{msg}さん。",
}
return render(request, "hello/index.html", params)
from django.urls import path
from . import views
# http://○○○/helloの後に続くアドレスを指定する
urlpatterns = [
path("", views.index, name="index"),
path("form", views.form, name="form"),
]
フォームの送信先
action="{% url 'form' %}"
urlpatternsにnameで登録したアドレスを利用する
CSRF対策
{% csrf_token %}
Cross Site Request Forgeries = リクエスト強要
外部からサイトへのフォーム送信などを行う攻撃
=>正しくフォームから送信されたアクセスかどうかをチェックする仕組み
Djangoのフォーム機能を使う
「送信するとフォームがクリアされてします」という状況を打破する
Formクラスを使う
Formクラスを作成してそこでフォームの内容を定義しておく
form.pyを作る
helloフォルダにform.pyを作成
Formクラスを使う
from django import forms
# label:それぞれのフィールドに設定するラベル名で、フィールドの手前にラベルのテキストが表示される
class HelloForm(forms.Form):
name = forms.CharField(label="name")
mail = forms.CharField(label="mail")
age = forms.IntegerField(label="age")
views.py
from django.shortcuts import render
from django.http import HttpResponse
from .form import HelloForm
# Create your views here.
# GETとPOSTの処理を記述
def index(request):
# 共通処理
params = {
"title": "Hello",
"message": "your data",
"form": HelloForm(),
}
# POST処理
if request.method == "POST":
params["message"] = (
"名前"
+ request.POST["name"]
+ "<br>メール:"
+ request.POST["mail"]
+ "<br>年齢:"
+ request.POST["age"]
)
# paramsのformの値を上書きして送られてきたフォームの値を持ったままHelloFormが作成される
params["form"] = HelloForm(request.POST)
return render(request, "hello/index.html", params)
index.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5">{{message | safe }}</p>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="click" class="btn btn-primary">
</form>
</body>
</html>
フィルター機能
htmlをそのまま出力できる
{{message | safe }}
urlpatterns.py
from django.urls import path
from . import views
# http://○○○/helloの後に続くアドレスを指定する
urlpatterns = [
path("", views.index, name="index"),
]
フィールドをタグで揃える
{{ form.as_table }}
{{ form.as_p }}
{{ form.as_ul }}
Bootstrapのクラスを適用する
from django import forms
class HelloForm(forms.Form):
name = forms.CharField(
label="name",
widget=forms.TextInput(
attrs={"class": "form-contorol"},
),
)
mail = forms.CharField(
label="mail",
widget=forms.TextInput(attrs={"class": "form-contorol"}),
)
age = forms.IntegerField(
label="age",
widget=forms.NumberInput(attrs={"class": "form-contorol"}),
)
以下はクラス名を設定する場合
forms.NumberInput(attrs={"属性名": "値"})
入力フィールド
CharField
文字のテキスト
EmailField
メールのテキスト
IntegerField
数字
FloatField
小数
URLField
URL
DateField
日付の形式のテキスト
TimeField
時刻の形式のテキスト
DateTimeField
日付と時刻を続けて書いたテキスト
チェックボックス
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5">{{ result | safe }}</p>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<table>
{{ form.as_p }}
<tr><td></td></tr>
<input type="submit" value="click" class="btn btn-primary my-2">
</table>
</form>
</body>
</html>
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import HelloForm
class HelloView(TemplateView):
# 初期化メソッド
def __init__(self, **kwargs):
self.params = {
"title": "hello",
"message": "your data",
"form": HelloForm(),
"result": None,
}
# getアクセスの処理
def get(self, request):
return render(request, "hello/index.html", self.params)
# POSTアクセスの処理
def post(self, request):
if "check" in request.POST:
self.params["result"] = "Checked!!"
else:
self.params["result"] = "not checked..."
self.params["form"] = HelloForm(request.POST)
return render(request, "hello/index.html", self.params)
NullBooleanField
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5">{{ result | safe }}</p>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<table>
{{ form.as_p }}
<tr><td></td></tr>
<input type="submit" value="click" class="btn btn-primary my-2">
</table>
</form>
</body>
</html>
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import HelloForm
class HelloView(TemplateView):
# 初期化メソッド
def __init__(self, **kwargs):
self.params = {
"title": "hello",
"message": "your data",
"form": HelloForm(),
"result": None,
}
# getアクセスの処理
def get(self, request):
return render(request, "hello/index.html", self.params)
# POSTアクセスの処理
def post(self, request):
chk = request.POST["check_data"]
self.params["result"] = f"you selected:{chk}."
self.params["form"] = HelloForm(request.POST)
return render(request, "hello/index.html", self.params)
from django import forms
class HelloForm(forms.Form):
check_data = forms.NullBooleanField(
label="check_data",
)
プルダウンメニュー(チョイス)
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}">
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5">{{ result | safe }}</p>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
<table>
{{ form.as_p }}
<tr><td></td></tr>
<input type="submit" value="click" class="btn btn-primary my-2">
</table>
</form>
</body>
</html>
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import HelloForm
class HelloView(TemplateView):
# 初期化メソッド
def __init__(self, **kwargs):
self.params = {
"title": "hello",
"message": "your data",
"form": HelloForm(),
"result": None,
}
# getアクセスの処理
def get(self, request):
return render(request, "hello/index.html", self.params)
# POSTアクセスの処理
def post(self, request):
chk = request.POST["choice"]
self.params["result"] = f"you selected:{chk}."
self.params["form"] = HelloForm(request.POST)
return render(request, "hello/index.html", self.params)
from django import forms
class HelloForm(forms.Form):
data = [
("one", "item1"),
("tow", "item2"),
("three", "item3"),
("fore", "item4"),
]
choice = forms.ChoiceField(
label="Choice",
choices=data,
)
ラジオボタン
複数の項目から一つを選ぶ
from django import forms
class HelloForm(forms.Form):
data = [
("one", "item1"),
("tow", "item2"),
("three", "item3"),
("fore", "item4"),
]
choice = forms.ChoiceField(
label="Choice",
choices=data,
widget=forms.RadioSelect(),
)
選択リスト
from django import forms
class HelloForm(forms.Form):
data = [
("one", "item1"),
("tow", "item2"),
("three", "item3"),
("fore", "item4"),
("five", "item5"),
]
choice = forms.ChoiceField(
label="Choice",
choices=data,
widget=forms.Select(
attrs={
"size": 5, # 属性所情報を用意することでリスト形式で表示
"class": "form-select",
}
),
)
複数の項目を取得する
複数項目の値はgetlistで
ch = request.POST.getlist("choice")
from django import forms
class HelloForm(forms.Form):
data = [
("one", "item1"),
("tow", "item2"),
("three", "item3"),
("fore", "item4"),
("five", "item5"),
]
choice = forms.MultipleChoiceField(
label="radio",
choices=data,
widget=forms.SelectMultiple(
attrs={
"size": 6,
"class": "form-select",
}
),
)
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import HelloForm
class HelloView(TemplateView):
# 初期化メソッド
def __init__(self, **kwargs):
self.params = {
"title": "hello",
"message": "your data",
"form": HelloForm(),
"result": None,
}
# getアクセスの処理
def get(self, request):
return render(request, "hello/index.html", self.params)
# POSTアクセスの処理
def post(self, request):
ch = request.POST.getlist("choice")
self.params["result"] = f"you selected:{str(ch)}."
self.params["form"] = HelloForm(request.POST)
return render(request, "hello/index.html", self.params)
リストの値を利用するには?
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import HelloForm
class HelloView(TemplateView):
# 初期化メソッド
def __init__(self, **kwargs):
self.params = {
"title": "hello",
"message": "your data",
"form": HelloForm(),
"result": None,
}
# getアクセスの処理
def get(self, request):
return render(request, "hello/index.html", self.params)
# POSTアクセスの処理
def post(self, request):
ch = request.POST.getlist("choice")
result = '<ol class="list-group"><b>selected:</b>'
for item in ch:
result += '<li class="list-group-item">' + item + "</li>"
result += "</ol>"
self.params["result"] = result
self.params["form"] = HelloForm(request.POST)
return render(request, "hello/index.html", self.params)
セッションの働き
クライアントとサーバーの間の接続を維持するための仕組み
「今アクセスしているのはこの人だ」という事をサーバー側で記憶し、そのクライアントが持っている情報を保管できるようにするもの
セッションの組み込み
セッション情報
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# 新規追加
"hello",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import SessionForm
class HelloView(TemplateView):
def __init__(self):
self.params = {
"title": "Hello",
"form": SessionForm(),
"result": None,
}
def get(self, request):
self.params["result"] = request.session.get("last_msg", "No message.")
return render(request, "hello/index.html", self.params)
def post(self, request):
ses = request.POST["session"]
self.params["result"] = f"send {ses} ."
request.session["last_msg"] = ses
self.params["form"] = SessionForm(request.POST)
return render(request, "hello/index.html", self.params)
from django import forms
class SessionForm(forms.Form):
session = forms.CharField(
label="session",
required=False,
widget=forms.TextInput(
attrs={
"class": "form-control",
}
),
)
セッションの値はアクセス時の処理を行う関数・メソッドの引数で渡されるHttpRequestインスタンスのsession属性に保管
SessionBase
○値の設定
・セッションに値を保管する
HttpRequest.session[キー]=値
・セッションから値を取り出す
変数=HttpRequest.session[キー]
値の設定は↑でOK、取り出す場合は、指定したキーの値が存在しなかった時にエラーが出るので以下のようにする
○値の取得
HttpRequest.session.get(キー,デフォルト値)
○値を取得してセッションから取り除く
HttpRequest.session.pop(キー,デフォルト値)
エラー対策
django.db.utils.OperationalError: no such table: django_session
対応策
python manage.py migrate
を実行する
ミドルウェア
django_app\django_app\settings.py
作成
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import SessionForm
class HelloView(TemplateView):
def __init__(self):
self.params = {
"title": "Hello",
"form": SessionForm(),
"result": None,
}
def get(self, request):
# last_msgというセッションの値をresultパラメータに設定
self.params["result"] = request.session.get("last_msg", "No message.")
return render(request, "hello/index.html", self.params)
def post(self, request):
ses = request.POST["session"]
self.params["result"] = f"send {ses} ."
request.session["last_msg"] = ses
self.params["form"] = SessionForm(request.POST)
return render(request, "hello/index.html", self.params)
# ミドルウェアの作成(アプリにアクセスするたびにセッションのcounterが+1される)
def sample_middleware(get_response):
def middleware(request):
counter = request.session.get("counter", 0)
request.session["counter"] = counter + 1
response = get_response(request)
print(f"count:{str(counter)}")
return response
return middleware
登録
#省略
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"hello.views.sample_middleware",
]
#省略
○ セッションの機能
セッションの全キー/値を取得する
SessionBase.keys()
SessionBase.items()
○セッションの全値を消去する
ただ値を消去する
SessionBase.clear()
セッション用のクッキーも削除する
SessionBase.flush()
○保持期間を設定する
SessionBase.set_expiry(整数)
情報の保持期間を秒単位で設定する
○ミドルウェア
クライアントから要求を受けて処理を行う過程に割り込んでなんらかの処理を実行させるためのプログラム
ミドルウェアはクライアントかあらのリクエストとレスポンスの間に割り込んで様々な処理を行う
これはアクセスがあると常に呼び出され実行される
→ミドルウェアを用意することでDjangoのアクセス処理に独自の機能を追加することができる
・ミドルウェアは関数名で識別される
def 関数A(get_response):
----初期化処理----
def 関数B(request):
ビューを実行する前の処理
response=get_response(request)
ビューを実行した後の処理
return 関数B
データベースあれこれ
・データベース
データベースの土台。テーブルをまとめておくための入れ物
・テーブル
テーブルは保存するデータの構造を定義する
・レコード
テーブルに保管されるデータ
マイグレーション
モデル=テーブル定義?
[ str ]
テキストの値を返すもの
○マイグレーション
データベースの移行を行うための機能
○マイグレーションファイルの作成
python .\manage.py makemigrations hello
(system) PS F:\Django_project\django_app> python .\manage.py makemigrations hello
Migrations for 'hello':
hello\migrations\0001_initial.py
+ Create model Friend
○マイグレーションを実行する
python .\manage.py migrate
(system) PS F:\Django_project\django_app> python .\manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, hello, sessions
Running migrations:
Applying hello.0001_initial... OK
管理ツールを使う
○管理者の作成
(system) PS F:\Django_project\django_app> python .\manage.py createsuperuser
Username (leave blank to use 'digital07'): admin
Email address: sample@mail.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
Friend登録
from django.contrib import admin
from .models import Friend
# Register your models here.
# Friendを登録
# あらかじめこのモデルが管理ツールで利用できるというように登録をする
admin.site.register(Friend)
○管理ツールにログインする
http://127.0.0.1:8000/admin/
○データを追加する
○登録データは__str__で用意した表示形式
○利用者の管理ページ
○利用者の追加
○パスワードの変更について
パスワードは暗号化されたパスワードが保存されているので、以下の「reset passowrd」からしか変更ができない。
データベースの読み込み&表示
○データの取得処理
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# Friendテーブルのレコードを全て取り出す
data = Friend.objects.all()
params = {
"title": "hello",
"message": "all friends",
"data": data,
}
return render(request, "hello/index.html", params)
○モデルの定義
from django.db import models
# Create your models here.
class Friend(models.Model):
name = models.CharField(max_length=100)
mail = models.EmailField(max_length=200)
gender = models.BooleanField()
age = models.IntegerField(default=0)
birthday = models.DateField()
def __str__(self):
return f"<Friend:id={str(self.id)},{self.name}({str(self.age)})>"
○モデルを使用できるようにする
from django.contrib import admin
from .models import Friend
# Register your models here.
# Friendを登録
# あらかじめこのモデルが管理ツールで利用できるというように登録をする
admin.site.register(Friend)
○表示ページを作成
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5 mt-4">{{ message | safe }}</p>
<table class="table">
<tr>
<th>ID</th>
<th>NAME</th>
<th>GENDER</th>
<th>MAIL</th>
<th>AGE</th>
<th>BIRTHDAY</th>
</tr>
{% for item in data %}
<tr>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>
{% if item.gender == Flase %}
male
{% else %}
female
{% endif %}
</td>
<td>{{item.mail}}</td>
<td>{{item.age}}</td>
<td>{{item.birthday}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
○ルーティング変更
from django.urls import path
from . import views
# http://○○○/helloの後に続くアドレスを指定する
urlpatterns = [
path("", views.index, name="index"),
]
指定IDのレコードを取り出す
フォームのクラス
from django import forms
class HelloForm(forms.Form):
id = forms.IntegerField(label="ID")
表示画面
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5 mt-4">{{ message | safe }}</p>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="click">
</form>
<hr>
<table class="table">
<tr>
<th>ID</th>
<th>NAME</th>
<th>GENDER</th>
<th>MAIL</th>
<th>AGE</th>
<th>BIRTHDAY</th>
</tr>
{% for item in data %}
<tr>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>
{% if item.gender == Flase %}
male
{% else %}
female
{% endif %}
</td>
<td>{{item.mail}}</td>
<td>{{item.age}}</td>
<td>{{item.birthday}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
処理
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
from .form import HelloForm
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
params = {
"title": "hello",
"message": "all friends",
"data": [],
"form": HelloForm(),
}
if request.method == "POST":
num = request.POST["id"]
item = Friend.objects.get(id=num)
params["data"] = [item]
params["form"] = HelloForm(request.POST)
else:
# Friendテーブルのレコードを全て取り出す
params["data"] = Friend.objects.all()
return render(request, "hello/index.html", params)
モデルのリストを調べる
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
from .form import HelloForm
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p class="h5 mt-4">{{ message | safe }}</p>
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="click">
</form>
<hr>
<p>{{data}}</p>
<table class="table">
<tr>
<th>data</th>
</tr>
{% for item in data %}
<tr>
<td>{{item}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
特定の項目だけ取り出す
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
from .form import HelloForm
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
data = Friend.objects.all().values("id", "name")
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
リストとして取り出す
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
from .form import HelloForm
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
data = Friend.objects.all().values("id", "name")
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
最初と最後、レコード数
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
from .form import HelloForm
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
num = Friend.objects.all().count()
# 最初のレコード取得
first = Friend.objects.all().first()
# 最後のレコード取得
last = Friend.objects.all().last()
data = [num, first, last]
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
QuerySetの表示をカスタマイズ
__str__
(オブジェクトをテキストとして取り出すメソッド)を変更することでこれを変更するとQuerySetをテキストにキャストした時の内容を変更することができる。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<table class="table">
{{ data | safe }}
</table>
</body>
</html>
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
from .form import HelloForm
from django.db.models import QuerySet
def __new_str__(self):
result = ""
for item in self:
result += "<tr>"
for k in item:
result += f"<td>{str(k)}={str(item[k])}<td>"
result += "<tr>"
return result
QuerySet.__str__ = __new_str__
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all().values("id", "name", "age")
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
Create
from django import forms
class HelloForm(forms.Form):
widget_attrs = {"class": "form-control"}
name = forms.CharField(
label="Name",
widget=forms.TextInput(attrs=widget_attrs),
)
mail = forms.EmailField(
label="Email",
widget=forms.EmailInput(attrs=widget_attrs),
)
gender = forms.BooleanField(
label="Gender",
required=False,
widget=forms.CheckboxInput(
attrs={
"class": "form-check",
}
),
)
age = forms.IntegerField(
label="Age",
widget=forms.NumberInput(
attrs=widget_attrs,
),
)
birthday = forms.DateField(
label="Birth",
widget=forms.DateInput(
attrs=widget_attrs,
),
)
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<form action="{% url 'create' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-primary mt-2" value="click">
</form>
</body>
</html>
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<table class="table">
<tr>
<th>data</th>
</tr>
{% for item in data %}
<tr>
<td>{{item}}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .models import Friend
from .form import HelloForm
from django.db.models import QuerySet
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
params = {
"title": "hello",
"form": HelloForm(),
}
# POSTを受信した際
if request.method == "POST":
# 送信された値を一通り変数に取り出す
name = request.POST["name"]
mail = request.POST["mail"]
gender = "gender" in request.POST
age = int(request.POST["age"])
birth = request.POST["birthday"]
# Friendインスタンスを作成
friend = Friend(
name=name,
mail=mail,
gender=gender,
age=age,
birthday=birth,
)
# データの保存
friend.save()
# 値のリダイレクト(to=~で指定)
return redirect(to="/hello")
return render(request, "hello/create.html", params)
from django.urls import path
from . import views
# http://○○○/helloの後に続くアドレスを指定する
urlpatterns = [
path("", views.index, name="index"),
path("create", views.create, name="create"),
]
ModelFormでもっと簡単に
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
from django import forms
from .models import Friend
class FriendForm(forms.ModelForm):
# Metaクラス・・・モデル用のフォームに関する情報が用意されている
class Meta:
model = Friend
fields = [
"name",
"mail",
"gender",
"age",
"birthday",
]
from django.urls import path
from . import views
# http://○○○/helloの後に続くアドレスを指定する
urlpatterns = [
path("", views.index, name="index"),
path("create", views.create, name="create"),
]
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<form action="{% url 'create' %}" method="post">
{% csrf_token %}
{{ form.as_table }}
<tr>
<th>
<td>
<input type="submit" class="btn btn-primary mt-2" value="click">
</td>
</th>
</tr>
</form>
</body>
</html>
Update
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
from django.urls import path
from . import views
# http://○○○/helloの後に続くアドレスを指定する
urlpatterns = [
path("", views.index, name="index"),
path("create", views.create, name="create"),
path("edit/<int:num>", views.edit, name="edit"),
]
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<form action="{% url 'create' %}" method="post">
{% csrf_token %}
{{ form.as_table }}
<tr>
<th>
<td>
<input type="submit" class="btn btn-primary mt-2" value="click">
</td>
</th>
</tr>
</form>
</body>
</html>
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<form action="{% url 'edit' id%}" method="post">
{% csrf_token %}
{{ form.as_table }}
<tr>
<th>
<td>
<input type="submit" class="btn btn-primary mt-2" value="click">
</td>
</th>
</tr>
</form>
</body>
</html>
Delete
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<form action="{% url 'edit' id%}" method="post">
{% csrf_token %}
{{ form.as_table }}
<tr>
<th>
<td>
<input type="submit" class="btn btn-primary mt-2" value="click">
</td>
</th>
</tr>
</form>
</body>
</html>
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<p>※以下のレコードを削除します。</p>
<table class="table">
<tr><th>ID</th><td>{{obj.id}}</td></tr>
<tr><th>Name</th><td>{{obj.name}}</td></tr>
<tr><th>Gender</th><td>
{% if obj.gender == False %}
male
{% else %}
female
{% endif %}
</td></tr>
<tr><th>Email</th><td>{{obj.mail}}</td></tr>
<tr><th>Age</th><td>{{obj.age}}</td></tr>
<tr><th>Birth</th><td>{{obj.birthday}}</td></tr>
<form action="{% url 'delete' id %}" method="post">
{% csrf_token %}
<tr>
<th></th>
<td>
<input type="submit" value="click" class="btn btn-primary">
</td>
</tr>
</form>
</table>
</body>
</html>
ジェネリックビュー
データを全部取りだす、指定のIDだけ取り出すなどの単純作業は自動でやってくれるビューといったものを用意してあればもっと作業が楽になる
↓
指定したモデルの全レコードを取り出したり、特定のIDのものだけを取り出すもっとも基本的な機能を持った既定のビュークラス
↓
これを使用することで面倒な処理を書くことは無くレコードを取り出せるようになる
ListView
指定モデルの全レコードを取り出すためのジェネリックビュー
クラス定義
from django.views.generic import ListView
class クラス名(ListView):
model = モデル
DetailView
特定のレコードだけを取り出すためのジェネリックビュー
クラス定義
from django.views.generic import DetailView
class クラス名( DetailView):
model = モデル
ジェネリックビューを使うとほとんどのビューの部分を作成することなくレコードの表示が行える
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from django.views.generic import ListView
from django.views.generic import DetailView
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
from django.urls import path
from . import views
from .views import FriendList
from .views import FriendDetail
# http://○○○/helloの後に続くアドレスを指定する
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"),
# .as_view()Viewインスタンスをして取り出せる(as_viewを付ければビューとしてPathに指定できる)
path("list", FriendList.as_view()),
# detail/番号でアクセスするとその番号がpkというパラメータとして渡される(pkというパラメータとして渡される)
path("detail/<int:pk>", FriendDetail.as_view()),
]
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<table class="table">
<tr>
<th>id</th>
<th>name</th>
<th></th>
</tr>
{% for item in object_list %}
<tr>
<th>{{item.id}}</th>
<th>{{item.name}}</th>
<th><a href="/hello/detail/{{item.id}}">detail</a></th>
</tr>
{% endfor %}
</table>
</body>
</html>
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<table class="table">
<tr>
<th>id</th>
<th>{{object.id}}</th>
</tr>
<tr>
<th>name</th>
<th>{{object.name}}</th>
</tr>
<tr>
<th>mail</th>
<th>{{object.mail}}</th>
</tr>
<tr>
<th>gender</th>
<th>{{object.gender}}</th>
</tr>
<tr>
<th>age</th>
<th>{{object.age}}</th>
</tr>
</table>
</body>
</html>
検索機能
from django.urls import path
from . import views
from .views import FriendList
from .views import FriendDetail
# http://○○○/helloの後に続くアドレスを指定する
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"),
# .as_view()Viewインスタンスをして取り出せる(as_viewを付ければビューとしてPathに指定できる)
path("list", FriendList.as_view()),
# detail/番号でアクセスするとその番号がpkというパラメータとして渡される(pkというパラメータとして渡される)
path("detail/<int:pk>", FriendDetail.as_view()),
# 検索機能追加
path("find", views.find, name="find"),
]
from django import forms
from .models import Friend
class FriendForm(forms.ModelForm):
# Metaクラス・・・モデル用のフォームに関する情報が用意されている
class Meta:
model = Friend
fields = [
"name",
"mail",
"gender",
"age",
"birthday",
]
# 検索用のフォーム
class FindForm(forms.Form):
find = forms.CharField(
label="Find",
required=False,
widget=forms.TextInput(
attrs=({"class": "form-control"}),
),
)
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
data = Friend.objects.filter(name=find)
msg = f"Result:{str(data.count())}"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p>{{ message | safe }}</p>
<hr>
<form action="{% url 'find' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="btn btn-primary mt-2" value="click">
</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>
<th>{{item.name}}({{item.age}})</th>
<th>{{item.mail}}</th>
</tr>
{% endfor %}
</table>
</body>
</html>
検索とフィルター
変数=Model.object.filter(フィルターの処理内容)
LIKE検索
- 値を含む検索
項目名__contains=値
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
# レコードからの検索
# data = Friend.objects.filter(name=find)
data = Friend.objects.filter(name__contains=find)
msg = f"Result:{str(data.count())}"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
-
値で始まるものを検索
項目名__startwith=値 -
値で終わるものを検索
項目名__endwith=値 -
大文字小文字を区別しない検索(完全一致)
項目名__iexact=値 -
大文字小文字を区別しない("i"を付ければ大文字小文字を区別しない)
項目名__icontains=値
項目名__istartswith=値
項目名__iendswith=値
data = Friend.objects.filter(name__contains=find)
data = Friend.objects.filter(name__icontains=find)
-
数値の比較(等しい)
項目名=値 -
数値の比較(値よりも大きい)
項目名__gt=値 -
数値の比較(等しいか大きいか)
項目名__gte=値 -
数値の比較(値よりも小さい)
項目名__lt=値 -
数値の比較(値と等しいか小さい)
項目名__lte=値
data = Friend.objects.filter(age__lte=int(find))
oo以上oo以下の設定
変数=モデル.objects.filter(1つ目の条件,2つ目の条件)
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
# レコードからの検索
# data = Friend.objects.filter(name=find)
# 大文字小文字区別しない
# data = Friend.objects.filter(name__icontains=find)
# 数値以下
# data = Friend.objects.filter(age__lte=int(find))
# oo以上oo以下
val = find.split()
data = Friend.objects.filter(
age__gte=val[0],
age__lte=val[1],
)
msg = f"Result:{str(data.count())}"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
別の書き方としてfilterメソッドを複数書く場合もOK
変数=モデル.objects
.filter(条件)
.filter(条件)
.filter(条件)
.filter(条件)
---省略---
複数の条件のどれかが合えば検索する
変数=モデル.objects.filter(Q(1つ目の条件) | Q(2つ目の条件))
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.db.models import Q
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
# OR検索
data = Friend.objects.filter(Q(name__contains=find) | Q(mail__contains=find))
msg = f"Result:{str(data.count())}"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
リストを使って検索
変数=モデル.objects.filter(項目名__in=リスト)
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.db.models import Q
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
list = find.split()
# OR検索
data = Friend.objects.filter(name__in=list)
msg = f"Result:{str(data.count())}"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
レコードの並び替え
モデル.objects.allやfilter.order_by(項目名)
逆順
モデル.objects.allやfilter.order_by(項目名).reverse
年齢順に並び替え
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.db.models import Q
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
# 年齢順に並び替え
data = Friend.objects.all().order_by("age")
msg = f"Result:{str(data.count())}"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
指定した範囲のレコードを取り出す
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.db.models import Q
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
params = {
"title": "hello",
"data": data,
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
list = find.split()
# 範囲指定して取り出す
data = Friend.objects.all()[int(list[0]) : int(list[1])]
msg = "result:"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
レコード集計とaggregate
変数=モデル.objects.aggregate( 関数 )
-
指定した項目のレコード数を返す
Count(項目名) -
指定した項目の合計を計算する
Sum(項目名) -
指定した項目の平均を計算する
Ave(項目名) -
指定した項目の最小値を返す
Min(項目名) -
指定した項目の最大値を返す
Max(項目名)
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.db.models import Q
from django.db.models import Count, Sum, Avg, Min, Max
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
re1 = Friend.objects.aggregate(Count("age"))
re2 = Friend.objects.aggregate(Sum("age"))
re3 = Friend.objects.aggregate(Avg("age"))
re4 = Friend.objects.aggregate(Min("age"))
re5 = Friend.objects.aggregate(Max("age"))
msg = f"count:{str(re1['age__count'])}<br>Sum:{str(re2['age__sum'])}<br>Average:{str(re3['age__avg'])}<br>Min:{str(re4['age__min'])}<br>Max:{str(re5['age__max'])}"
params = {"title": "hello", "data": data, "message": msg}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
list = find.split()
# 範囲指定して取り出す
data = Friend.objects.all()[int(list[0]) : int(list[1])]
msg = "result:"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
Count("age")
で値は取り出せるが得られるのは辞書型のデータ
値の取り出しは'項目名__関数名'で取り出し可能
SQLを直接実行する場合
変数=モデル.objects.raw(クリエ文)
バリデーションチェック
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from .form import CheckForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.db.models import Q
from django.db.models import Count, Sum, Avg, Min, Max
# データベースを扱う際は関数方式の方がやりやすい
def index(request):
# 取得したレコード数
data = Friend.objects.all()
re1 = Friend.objects.aggregate(Count("age"))
re2 = Friend.objects.aggregate(Sum("age"))
re3 = Friend.objects.aggregate(Avg("age"))
re4 = Friend.objects.aggregate(Min("age"))
re5 = Friend.objects.aggregate(Max("age"))
msg = f"count:{str(re1['age__count'])}<br>Sum:{str(re2['age__sum'])}<br>Average:{str(re3['age__avg'])}<br>Min:{str(re4['age__min'])}<br>Max:{str(re5['age__max'])}"
params = {"title": "hello", "data": data, "message": msg}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
list = find.split()
# 範囲指定して取り出す
data = Friend.objects.all()[int(list[0]) : int(list[1])]
msg = "result:"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
# check関数
def check(request):
params = {
"title": "Hello",
"message:": "check validation.",
"form": CheckForm(),
}
if request.method == "POST":
form = CheckForm(request.POST)
params["form"] = form
if form.is_valid():
params["message:"] = "OK"
else:
params["message:"] = "not good"
return render(request, "hello/check.html", params)
バリデーション
値のチェック
フォームなどの入力項目に条件を設定して、その条件を満たしているかどうかを確認する
バリデーションをチェックする
if( From .is_valid()):
----正常時の処理----
else:
----エラー時の処理----
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<form action="{% url 'check' %}" method="post">
{% csrf_token %}
{{ form.as_table }}
<tr>
<th>
<td>
<input type="submit" class="btn btn-primary mt-2" value="click">
</td>
</th>
</tr>
</form>
</body>
</html>
from django.urls import path
from . import views
from .views import FriendList
from .views import FriendDetail
# http://○○○/helloの後に続くアドレスを指定する
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"),
# .as_view()Viewインスタンスをして取り出せる(as_viewを付ければビューとしてPathに指定できる)
path("list", FriendList.as_view()),
# detail/番号でアクセスするとその番号がpkというパラメータとして渡される(pkというパラメータとして渡される)
path("detail/<int:pk>", FriendDetail.as_view()),
# 検索機能追加
path("find", views.find, name="find"),
# バリデーションチェック
path("check", views.check, name="check"),
]
from django import forms
from .models import Friend
class FriendForm(forms.ModelForm):
# Metaクラス・・・モデル用のフォームに関する情報が用意されている
class Meta:
model = Friend
fields = [
"name",
"mail",
"gender",
"age",
"birthday",
]
# 検索用のフォーム
class FindForm(forms.Form):
find = forms.CharField(
label="Find",
required=False,
widget=forms.TextInput(
attrs=({"class": "form-control"}),
),
)
# バリデーション用のフォーム
class CheckForm(forms.Form):
str = forms.CharField(
label="Name",
widget=forms.TextInput(attrs={"class": "form-contol"}),
)
## 空欄・文字数・数字の範囲
from django import forms
from .models import Friend
class FriendForm(forms.ModelForm):
# Metaクラス・・・モデル用のフォームに関する情報が用意されている
class Meta:
model = Friend
fields = [
"name",
"mail",
"gender",
"age",
"birthday",
]
# 検索用のフォーム
class FindForm(forms.Form):
find = forms.CharField(
label="Find",
required=False,
widget=forms.TextInput(
attrs=({"class": "form-control"}),
),
)
# バリデーション用のフォーム
class CheckForm(forms.Form):
empty = forms.CharField(
label="Enpty",
empty_value=True,
widget=forms.TextInput(attrs={"class": "form-control"}),
)
# 数字を入力
min = forms.IntegerField(
label="Min",
min_value=10,
widget=forms.NumberInput(attrs={"class": "form-control"}),
)
# 文字数制限
max = forms.CharField(
label="Max",
max_length=100,
widget=forms.TextInput(attrs={"class": "form-control"}),
)
日時関連のバリデーション
%y:年
%m:月
%d:日
%H:時
%M:分
%S:秒
from django import forms
from .models import Friend
class FriendForm(forms.ModelForm):
# Metaクラス・・・モデル用のフォームに関する情報が用意されている
class Meta:
model = Friend
fields = [
"name",
"mail",
"gender",
"age",
"birthday",
]
# 検索用のフォーム
class FindForm(forms.Form):
find = forms.CharField(
label="Find",
required=False,
widget=forms.TextInput(
attrs=({"class": "form-control"}),
),
)
# バリデーション用のフォーム
class CheckForm(forms.Form):
empty = forms.CharField(
label="Enpty",
empty_value=True,
widget=forms.TextInput(attrs={"class": "form-control"}),
)
# 数字を入力
min = forms.IntegerField(
label="Min",
min_value=10,
widget=forms.NumberInput(attrs={"class": "form-control"}),
)
# 文字数制限
max = forms.CharField(
label="Max",
max_length=100,
widget=forms.TextInput(attrs={"class": "form-control"}),
)
# 日付
date = forms.DateField(
label="Date",
input_formats=["%d"],
widget=forms.DateInput(
attrs={
"class": "form-control",
"type": "date",
}
),
)
# 時間
datetime = forms.DateTimeField(
label="DateTime",
widget=forms.DateTimeInput(
attrs={
"class": "form-control",
"type": "datetime-local",
}
),
)
バリデーションの追加
class クラス名 (forms.Form):
---項目の用意---
def clean(self):
変数=super().clean()
---値の処理---
save()のタイミングでバリデーションチェックが実行される
モデルのバリデーション
基本的にmodels.pyで設定できることしかバリデーションチェックは出来ない
from django.db import models
# Create your models here.
class Friend(models.Model):
name = models.CharField(max_length=100)
mail = models.EmailField(max_length=200)
gender = models.BooleanField()
age = models.IntegerField(default=0)
birthday = models.DateField()
# check関数
def check(request):
params = {
"title": "Hello",
"message": "check validation.",
"form": FriendForm(),
}
if request.method == "POST":
obj = Friend()
form = FriendForm(request.POST, instance=obj)
params["form"] = form
if form.is_valid():
params["message"] = "OK!"
else:
params["message"] = "no good"
return render(request, "hello/check.html", params)
年齢にバリデーションチェックをかける
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
# Create your models here.
# バリデーションルールの組み込み
class Friend(models.Model):
name = models.CharField(max_length=100)
mail = models.EmailField(max_length=200)
gender = models.BooleanField()
age = models.IntegerField(
validators=[
MinValueValidator(0),
MaxValueValidator(150),
]
)
birthday = models.DateField()
## その他バリデーションチェック
from django.db import models
from django.core.validators import (
MinValueValidator,
MaxValueValidator,
MaxLengthValidator,
MinLengthValidator,
)
# Create your models here.
# バリデーションルールの組み込み
class Friend(models.Model):
name = models.CharField(
max_length=100,
validators=[
MaxLengthValidator(100),
MinLengthValidator(1),
],
)
mail = models.EmailField()
gender = models.BooleanField()
age = models.IntegerField(
validators=[
MinValueValidator(0),
MaxValueValidator(150),
]
)
birthday = models.DateField()
URLにバリデーション
from django.db import models
from django.core.validators import (
MinValueValidator,
MaxValueValidator,
MaxLengthValidator,
MinLengthValidator,
URLValidator,
)
# Create your models here.
# バリデーションルールの組み込み
class Friend(models.Model):
name = models.CharField(
max_length=100,
validators=[
URLValidator(),
MaxLengthValidator(100),
MinLengthValidator(1),
],
)
mail = models.EmailField()
gender = models.BooleanField()
age = models.IntegerField(
validators=[
MinValueValidator(0),
MaxValueValidator(150),
]
)
birthday = models.DateField()
null文字の禁止
from django.db import models
from django.core.validators import (
MinValueValidator,
MaxValueValidator,
MaxLengthValidator,
MinLengthValidator,
URLValidator,
ProhibitNullCharactersValidator,
)
# Create your models here.
# バリデーションルールの組み込み
class Friend(models.Model):
name = models.CharField(
max_length=100,
validators=[
URLValidator(),
MaxLengthValidator(100),
MinLengthValidator(1),
ProhibitNullCharactersValidator(),
],
)
mail = models.EmailField()
gender = models.BooleanField()
age = models.IntegerField(
validators=[
MinValueValidator(0),
MaxValueValidator(150),
]
)
birthday = models.DateField()
正規表現
from django.db import models
from django.core.validators import (
MinValueValidator,
MaxValueValidator,
MaxLengthValidator,
MinLengthValidator,
URLValidator,
ProhibitNullCharactersValidator,
RegexValidator,
)
# Create your models here.
# バリデーションルールの組み込み
class Friend(models.Model):
name = models.CharField(
max_length=100,
validators=[
URLValidator(),
MaxLengthValidator(100),
MinLengthValidator(1),
ProhibitNullCharactersValidator(),
# a~zの小文字のみの入力してい
RegexValidator(r"^[a-z]*$"),
],
)
mail = models.EmailField()
gender = models.BooleanField()
age = models.IntegerField(
validators=[
MinValueValidator(0),
MaxValueValidator(150),
]
)
birthday = models.DateField()
バリデーター関数を作る
from django.db import models
from django.core.validators import (
MinValueValidator,
MaxValueValidator,
MaxLengthValidator,
MinLengthValidator,
URLValidator,
ProhibitNullCharactersValidator,
RegexValidator,
)
from django.core.exceptions import ValidationError
import re
def number_only(value):
if re.match(r"^[0-9]*$", value) == None:
raise ValidationError(
"%(value)s is not Number!,",
params={"value": value},
)
# Create your models here.
# バリデーションルールの組み込み
class Friend(models.Model):
name = models.CharField(
max_length=100,
validators=[number_only],
)
mail = models.EmailField()
gender = models.BooleanField()
age = models.IntegerField(
validators=[
MinValueValidator(0),
MaxValueValidator(150),
]
)
birthday = models.DateField()
フォームとエラーメッセージを個別に表示する
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<p>{{message | safe}}</p>
<hr>
<ol class="list-group">
{% for item in form %}
<li class="list-group-item py-2">
{{item.name}}({{item.value}}):{{item.errors.as_text}}
</li>
{% endfor %}
</ol>
<table class="table mt-4">
<form action="{% url 'check' %}" method="post">
{% csrf_token %}
<tr><th>名前</th><td>{{form.name}}</td></tr>
<tr><th>メール</th><td>{{form.mail}}</td></tr>
<tr><th>性別</th><td>{{form.gender}}</td></tr>
<tr><th>年齢</th><td>{{form.age}}</td></tr>
<tr><th>誕生日</th><td>{{form.birthday}}</td></tr>
<tr>
<td></td>
<td>
<input type="submit" value="click" class="btn btn-primary">
</td>
</tr>
</form>
</table>
</body>
</html>
エラーメッセージの出し方
{form.errors}}
{% for item in form %}
<li class="list-group-item py-2">
{{item.name}}({{item.value}}):{{item.errors.as_text}}
</li>
{% endfor %}
オブジェクトをforで取り出す。
その後そのオブジェクトから個々の情報を取り出す。
また、「errors」はその後に「as_text」を付けることでテキストとして値を取り出せる
ModelFormのカスタマイズ
from django import forms
from .models import Friend
class FriendForm(forms.ModelForm):
# Metaクラス・・・モデル用のフォームに関する情報が用意されている
class Meta:
model = Friend
fields = [
"name",
"mail",
"gender",
"age",
"birthday",
]
# フィールド名をキーにしてウィジェットのインスタンスを設定する。
#
widgets = {
"name": forms.TextInput(attrs={"class": "form-control"}),
"mail": forms.EmailInput(attrs={"class": "form-control"}),
"age": forms.NumberInput(attrs={"class": "form-control"}),
"birthday": forms.DateInput(
attrs={"class": "form-control", "type": "date-local"}
),
}
# 検索用のフォーム
class FindForm(forms.Form):
find = forms.CharField(
label="Find",
required=False,
widget=forms.TextInput(
attrs=({"class": "form-control"}),
),
)
# バリデーション用のフォーム
class CheckForm(forms.Form):
str = forms.CharField(
label="String", widget=forms.TextInput(attrs={"class": "form-control"})
)
def clean(self):
cleaned_data = super().clean()
str = cleaned_data["str"]
if str.lower().startswith("no"):
raise forms.ValidationError('you input "NO!!"')
ペネトレーション
データを整理して表示させる機能
ページ分けの機能。テーブルに保存nされているレコードを一定ごとに分けることでたくさんのレコードがあってもデータを使いやすくする
使い方
変数=Paginator(コレクション,レコード数)
インスタンスを作成するにはレコード全体をまとめたコレクションと1ページあたりのレコード数の2つを引数として用意する必要がある。
コレクション:リストやセット辞書等。allやfillterで得られるオブジェクト(QuerySet)
指定ページのレコードを取り出す
変数=Paginatorオブジェクト.get_page(番号)
引数にページ番号の整数を指定すればそのpw-時のレコードをまとめて取り出すことができる
指定ページ番号のレコードが見つからない場合は最後のページのレコードを返す
得られるのが「Page」クラスのインスタンス。forとかで要素を取り出す
使ってみる
from django.urls import path
from . import views
from .views import FriendList
from .views import FriendDetail
# http://○○○/helloの後に続くアドレスを指定する
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"),
# .as_view()Viewインスタンスをして取り出せる(as_viewを付ければビューとしてPathに指定できる)
path("list", FriendList.as_view()),
# detail/番号でアクセスするとその番号がpkというパラメータとして渡される(pkというパラメータとして渡される)
path("detail/<int:pk>", FriendDetail.as_view()),
# 検索機能追加
path("find", views.find, name="find"),
# バリデーションチェック
path("check", views.check, name="check"),
# ペネトレーション
path("<int:num>", views.index, name="index"),
]
from django.shortcuts import render
from django.shortcuts import redirect
from django.http import HttpResponse
from django.views.generic import TemplateView # 追加
from .form import FriendForm
from .models import Friend
from .form import FindForm
from .form import CheckForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.db.models import Q
from django.db.models import Count, Sum, Avg, Min, Max
from django.core.paginator import Paginator
# データベースを扱う際は関数方式の方がやりやすい
def index(request, num=1):
# 取得したレコード数
data = Friend.objects.all()
page = Paginator(data, 3)
params = {
"title": "hello",
"data": page.get_page(num),
"message": "",
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
list = find.split()
# 範囲指定して取り出す
data = Friend.objects.all()[int(list[0]) : int(list[1])]
msg = "result:"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
# check関数
def check(request):
params = {
"title": "Hello",
"message": "check validation.",
"form": FriendForm(),
}
if request.method == "POST":
obj = Friend()
form = FriendForm(request.POST, instance=obj)
params["form"] = form
if form.is_valid():
params["message"] = "OK!"
else:
params["message"] = "no good"
return render(request, "hello/check.html", params)
# ページの移動
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
{{message | safe}}
<table class="table">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<th>mail</th>
<th>birthday</th>
</tr>
{% for item in data %}
<tr>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>{{item.mail}}</td>
<td>{{item.birthday}}</td>
</tr>
{% endfor %}
</table>
<ul class="pagination justify-content-center">
{% if data.has_previous %}
<li class="page-item">
<a href="{% url 'index' %}{{data.previous_page_number}}" class="page-link">« prev</a>
</li>
<li class="page-item">
<a href="{% url 'index' %}"{{data.previous_page_number}} class="page-link">« prev</a>
</li>
{% else %}
<li class="page-item">
<a href="" class="page-link">« first</a>
</li>
<li class="page-item">
<a href="" class="page-link">« prev</a>
</li>
{% endif %}
<li class="page-item">
<a href="" class="page-link">{{data.number}}/{{data.paginator.num_pages}}</a>
</li>
{% if data.has_next %}
<li class="page-item">
<a href="{% url 'index' %}{{ data.next_page_number }}" class="page-link">next »</a>
</li>
<li class="page-item">
<a href="{% url 'index' %}{{ data.next_page_number }}" class="page-link">last »</a>
</li>
{% else %}
<li class="page-item">
<a href="" class="page-link">next »</a>
</li>
<li class="page-item">
<a href="" class="page-link">last »</a>
</li>
{% endif %}
</ul>
</body>
</html>
{% if data.has_previous %}
:前のページがあるか調べる
{{data.previous_page_number}}
:前のページ番号を返す。hello/番号のアドレスを生成している
{% if data.has_next %}
:次のページがあるか調べる
messageページの作成
from django.urls import path
from . import views
from .views import FriendList
from .views import FriendDetail
# http://○○○/helloの後に続くアドレスを指定する
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"),
# .as_view()Viewインスタンスをして取り出せる(as_viewを付ければビューとしてPathに指定できる)
path("list", FriendList.as_view()),
# detail/番号でアクセスするとその番号がpkというパラメータとして渡される(pkというパラメータとして渡される)
path("detail/<int:pk>", FriendDetail.as_view()),
# 検索機能追加
path("find", views.find, name="find"),
# バリデーションチェック
path("check", views.check, name="check"),
# ペネトレーション
path("<int:num>", views.index, name="index"),
# メッセージ
path("message/", views.message, name="message"),
path("message/<int:page>", views.message, name="message"),
]
from django import forms
from .models import Friend, Message
class FriendForm(forms.ModelForm):
# Metaクラス・・・モデル用のフォームに関する情報が用意されている
class Meta:
model = Friend
fields = [
"name",
"mail",
"gender",
"age",
"birthday",
]
# フィールド名をキーにしてウィジェットのインスタンスを設定する。
#
widgets = {
"name": forms.TextInput(attrs={"class": "form-control"}),
"mail": forms.EmailInput(attrs={"class": "form-control"}),
"age": forms.NumberInput(attrs={"class": "form-control"}),
"birthday": forms.DateInput(
attrs={"class": "form-control", "type": "date-local"}
),
}
# 検索用のフォーム
class FindForm(forms.Form):
find = forms.CharField(
label="Find",
required=False,
widget=forms.TextInput(
attrs=({"class": "form-control"}),
),
)
# バリデーション用のフォーム
class CheckForm(forms.Form):
str = forms.CharField(
label="String", widget=forms.TextInput(attrs={"class": "form-control"})
)
def clean(self):
cleaned_data = super().clean()
str = cleaned_data["str"]
if str.lower().startswith("no"):
raise forms.ValidationError('you input "NO!!"')
# Message
class MessageForm(forms.ModelForm):
class Meta:
model = Message
fields = [
"title",
"content",
"friend",
]
widgets = {
"title": forms.TextInput(
attrs={"class": "form-control form-control-sm"},
),
"content": forms.TextInput(
attrs={
"class": "form-control form-control-sm",
"rows": 2,
}
),
"friend": forms.Select(attrs={"class": "form-control form-control-sm"}),
}
from django.shortcuts import render
from django.shortcuts import redirect
from .form import FriendForm, MessageForm
from .models import Friend, Message
from .form import FindForm
from django.views.generic import ListView
from django.views.generic import DetailView
from django.core.paginator import Paginator
# データベースを扱う際は関数方式の方がやりやすい
def index(request, num=1):
# 取得したレコード数
data = Friend.objects.all()
page = Paginator(data, 3)
params = {
"title": "hello",
"data": page.get_page(num),
"message": "",
}
return render(request, "hello/index.html", params)
# create model
def create(request):
if request.method == "POST":
# Friendクラスのインスタンスを作成(初期状態)
obj = Friend()
# FriendFormクラスインスタンスを作成
friend = FriendForm(
request.POST, # POST送信されたデータがまとめてある
instance=obj,
)
friend.save()
return redirect(to="/hello")
params = {
"title": "hello",
"form": FriendForm(),
}
return render(request, "hello/create.html", params)
# edit
def edit(request, num):
# IDに対応するデータの取得
obj = Friend.objects.get(id=num)
if request.method == "POST":
friend = FriendForm(request.POST, instance=obj)
friend.save()
return redirect(to="/hello")
params = {"title": "Hello", "id": num, "form": FriendForm(instance=obj)}
return render(request, "hello/edit.html", params)
# delete
def delete(request, num):
friend = Friend.objects.get(id=num)
if request.method == "POST":
friend.delete()
return redirect(to="/hello")
params = {
"title": "Hello",
"id": num,
"obj": friend,
}
return render(request, "hello/delete.html", params)
# ジェネリッククラスを追加
class FriendList(ListView):
model = Friend
class FriendDetail(DetailView):
model = Friend
# 検索
def find(request):
if request.method == "POST":
form = FindForm(request.POST)
find = request.POST["find"]
list = find.split()
# 範囲指定して取り出す
data = Friend.objects.all()[int(list[0]) : int(list[1])]
msg = "result:"
else:
msg = "search words..."
form = FindForm()
data = Friend.objects.all()
params = {
"title": "Hello",
"message": msg,
"form": form,
"data": data,
}
return render(request, "hello/find.html", params)
# check関数
def check(request):
params = {
"title": "Hello",
"message": "check validation.",
"form": FriendForm(),
}
if request.method == "POST":
obj = Friend()
form = FriendForm(request.POST, instance=obj)
params["form"] = form
if form.is_valid():
params["message"] = "OK!"
else:
params["message"] = "no good"
return render(request, "hello/check.html", params)
# message
def message(request, page=1):
# メッセージの保存
if request.method == "POST":
obj = Message()
form = MessageForm(request.POST, instance=obj)
form.save()
# メッセージをPaginatorで取り出す
data = Message.objects.all().reverse()
paginator = Paginator(data, 5)
params = {
"title": "Message",
"form": MessageForm(),
"data": paginator.get_page(page),
}
return render(request, "hello/message.html", params)
{% load static %}
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
<hr>
<form action="{% url 'message' %}" method="post">
{% csrf_token %}
<!-- FriendFormの書き出し -->
{{form.as_p}}
<!-- send -->
<input type="submit" value="send" class="btn btn-primary">
<div class="mt-5"></div>
<table class="table">
<tr>
<th class="py-1">title</th>
<th class="py-1">name</th>
<th class="py-1">datetime</th>
</tr>
{% for item in data %}
<tr>
<td class="py-2">{{item.title}}</td>
<!-- Messageに関連付けされているFriendのnameを出力したもの -->
<!-- リレーションでは設定項目を用意してある従テーブル側では関連する相手のモデルがそのまま属性として保管されている -->
<td class="py-2">{{item.friend.name}}</td>
<td class="py-2">{{item.pub_date}}</td>
</tr>
{% endfor %}
</table>
<ul class="pagination justify-content-center">
{% if data.has_previous %}
<li class="page-item">
<a href="{% url 'message' %}" class="page-link">« first</a>
</li>
<li class="page-item">
<a href="{% url 'message' %}{{data.previous_page_number}}" class="page-link">« prev</a>
</li>
{% else %}
<li class="page-item">
<a href="" class="page-link">« first</a>
</li>
<li class="page-item">
<a href="" class="page-link">« prev</a>
</li>
{% endif %}
<li class="page-item">
<a href="" class="page-link">{{data.number}}/{{data.paginator.num_pages}}</a>
</li>
{% if data.has_next %}
<li class="page-item">
<a href="{% url 'message' %}{{data.next_page_number}}" class="page-link">« next</a>
</li>
<li class="page-item">
<a href="{% url 'message' %}{{data.paginator.num_pagtes}}" class="page-link">« last</a>
</li>
{% else %}
<li class="page-item">
<a href="" class="page-link">next »</a>
</li>
<li class="page-item">
<a href="" class="page-link">last »</a>
</li>
{% endif %}
</ul>
</form>
</body>
</html>
indexに投稿メッセージを表示する
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<!-- <link rel="stylesheet" type="text/css" href="{% static 'hello/css/style.css' %}"> -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body class="container">
<h1 class="display-4 text-primary mb-4">{{title}}</h1>
{{message | safe}}
<table class="table">
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<th>mail</th>
<th>birthday</th>
<th>message</th>
</tr>
{% for item in data %}
<tr>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>{{item.mail}}</td>
<td>{{item.birthday}}</td>
<td>
<ul>
{% for ob in item.message_set.add %}
<li>{{obj.title}}</li>
{% endfor %}
</ul>
</td>
</tr>
{% endfor %}
</table>
<ul class="pagination justify-content-center">
<!-- 前ページに移動ボタン -->
{% if data.has_previous %}
<!-- リンクの用意 -->
<li class="page-item">
<a href="{% url 'index' %}{{data.previous_page_number}}" class="page-link">« prev</a>
</li>
<li class="page-item">
<a href="{% url 'index' %}{{data.previous_page_number}}" class="page-link">« prev</a>
</li>
<!-- リンクの無い表示を用意 -->
{% else %}
<li class="page-item">
<a href="" class="page-link">« first</a>
</li>
<li class="page-item">
<a href="" class="page-link">« prev</a>
</li>
{% endif %}
<li class="page-item">
<a href="" class="page-link">{{data.number}}/{{data.paginator.num_pages}}</a>
</li>
{% if data.has_next %}
<li class="page-item">
<a href="{% url 'index' %}{{ data.next_page_number }}" class="page-link">next »</a>
</li>
<li class="page-item">
<a href="{% url 'index' %}{{ data.next_page_number }}" class="page-link">last »</a>
</li>
{% else %}
<li class="page-item">
<a href="" class="page-link">next »</a>
</li>
<li class="page-item">
<a href="" class="page-link">last »</a>
</li>
{% endif %}
</ul>
</body>
</html>