【Python】Django ~ 基本編 / model ~

■ はじめに

https://dk521123.hatenablog.com/entry/2022/08/07/121017
https://dk521123.hatenablog.com/entry/2022/08/08/140619
https://dk521123.hatenablog.com/entry/2022/08/09/092941

の続き。

Django (ジャンゴ)  の ビューに関する操作をやってきたので、
今回は、model (モデル) について扱っていく。

目次

【0】今回、勉強すること
【1】前提知識
 1)データベースの設定
【2】モデル定義
 1)サンプル
【3】関連コマンド
 1)makemigrationsコマンド
 2)migrateコマンド
【4】管理画面
 1)createsuperuserコマンド
 2)管理画面
【5】モデルをビューで表示する
 0)ビュー以外のパート
 1)CreateView
 2)ListView
 3)DetailView
 4)DeleteView
 5)UpdateView 

【0】今回、勉強すること

1)モデル
2)管理画面
3)ビュー
 + CreateView
 + ListView
 + DetailView
 + DeleteView
 + UpdateView

【1】前提知識

1)データベースの設定

* デフォルトでは、SQLiteを使用するようになっている

helloworld/helloworld/settings.py

# より抜粋

# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

【2】モデル定義

https://dk521123.hatenablog.com/entry/2022/08/09/092941

で作成したアプリ内に「models.py」があるので
そこに定義を書いていく

1)サンプル

helloworld/helloworldapp/models.py

from django.db import models

# Create your models here.
class SampleModel(models.Model):
  no = models.BigIntegerField()
  name = models.CharField(max_length=50)
  modified_at = models.DateTimeField()
  created_at = models.DateTimeField()

【3】関連コマンド

「【2】モデル定義」で定義したPythonコードを
使用しているDBに反映が必要になる。

その際、以下の2つのコマンドを使う。
~~~~
1)makemigrationsコマンド
2)migrateコマンド
~~~~

1)makemigrationsコマンド

 作成したモデルから、
データベースへの定義に必要な中間ファイルを生成するコマンド

コマンド

python manage.py makemigrations

# アプリごとに実行する場合
python manage.py makemigrations <アプリ名>

コマンド例

python manage.py makemigrations

~~~出力結果~~~
Migrations for 'helloworldapp':
  helloworldapp\migrations\0001_initial.py <= 出力ファイル
    - Create model SampleModel

2)migrateコマンド

「1)makemigrationsコマンド」で作成したファイルを
データベースに反映させるコマンド

コマンド例

python manage.py migrate

~~~出力結果~~~
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, helloworldapp, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  ... 略
  Applying helloworldapp.0001_initial... OK
  Applying sessions.0001_initial... OK

【4】管理画面

* モデルに簡単にデータを追加する手順を記載する

1)createsuperuserコマンド

* 管理者ユーザーを作成/追加するコマンド

https://yu-nix.com/archives/django-createsuperuser/

コマンド例

python manage.py createsuperuser

~~~出力結果・入力例~~~
Username (leave blank to use 'user'): root
Email address: xxxx@xxxx.com
Password: 
Password (again):
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

# Bypass password validation and create user anyway?
# [訳] とりあえず、パスワード検証を回避し、ユーザを作成する?
#  => 「パスワードが短いけど、大丈夫?」ってこと

2)管理画面

* 以下の順序で、モデルにデータを追加する
~~~~~~~
[1] サーバを立ち上げる
[2] 管理画面にアクセスする
[3] モデルと登録する
[4] 管理画面からモデルにデータを追加
~~~~~~~

[1] サーバを立ち上げる

python manage.py runserver

[2] 管理画面にアクセスする

以下のサイトをブラウザでアクセスする
 => 認証情報は「1)createsuperuserコマンド」で
  設定したユーザとパスワードを入力する

http://127.0.0.1:8000/admin/

[3] モデルと登録する

# helloworld/helloworldapp/admin.py を以下のようにする

from django.contrib import admin
from .models import SampleModel

# Register your models here.
admin.site.register(SampleModel)

[4] 管理画面からモデルにデータを追加

 管理画面をリロードすると
「Sample models」リンクが表示されるので、
その隣の「ADD」リンクを押下すると、
登録したモデルに入力する画面が表示されるので
データを追加する

【5】モデルをビューで表示する

* 以下のビューを追加する。
 1)CreateView
 2)ListView
 3)DetailView
 4)DeleteView
 5)UpdateView

0)ビュー以外のパート

helloworld/helloworldapp/views.py

from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import CreateView
from django.views.generic import ListView
from django.views.generic import DetailView
from django.views.generic import DeleteView
from django.views.generic import UpdateView
from .models import SampleModel

class HelloCreateView(CreateView):
  template_name = 'new.html'
  model = SampleModel
  # ↓がないと、エラー「without the 'fields' attribute is prohibited.」
  # って言われる
  fields = ('no', 'name', 'modified_at', 'created_at')
  # ↓がないと、エラー「No URL to redirect to.
  # Either provide a url or define a get_absolute_url method on the Model.」
  # って言われる
  success_url = reverse_lazy('list')

class HelloListView(ListView):
  template_name = 'list.html'
  model = SampleModel

class HelloDetailView(DetailView):
  template_name = 'detail.html'
  model = SampleModel

class HelloDeleteView(DeleteView):
  template_name = 'delete.html'
  model = SampleModel
  success_url = reverse_lazy('list')

class HelloUpdateView(UpdateView):
  template_name = 'update.html'
  model = SampleModel
  fields = ('no', 'name', 'modified_at', 'created_at')
  success_url = reverse_lazy('list')

helloworld/helloworldapp/urls.py

from django.urls import path
from .views import HelloCreateView
from .views import HelloListView
from .views import HelloDetailView
from .views import HelloUpdateView
from .views import HelloDeleteView

urlpatterns = [
  path('helloworldapp/new',
    HelloCreateView.as_view(),
    name='new'),
  path('helloworldapp/list',
    HelloListView.as_view(),
    name='list'),
  path('helloworldapp/detail/<int:pk>/',
    HelloDetailView.as_view(),
    name='detail'),
  path('helloworldapp/update/<int:pk>/',
    HelloUpdateView.as_view(),
    name='update'),
  path('helloworldapp/delete/<int:pk>/',
    HelloDeleteView.as_view(),
    name='delete'),
]

1)CreateView

helloworld/templates/new.html

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <title>new</title>
</head>
<body>
<h1>New</h1>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Register">
</form>
</body>
</html>

2)ListView

helloworld/templates/list.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>ListView</title>
</head>
<body>
  <h1>List</h1>
  <a href="{% url 'new' %}">New</a>
  <table border="1">
    <tr>
      <th>no</th>
      <th>name</th>
      <th>Detail</th>
      <th>Update</th>
      <th>Delete</th>
    </tr>
    {% for item in object_list %}
    <tr>
      <td>{{ item.no }}</td>
      <td>{{ item.name }}</td>
      <th><a href="{% url 'detail' item.pk %}">Detail</a></th>
      <th><a href="{% url 'update' item.pk %}">Update</a></th>
      <th><a href="{% url 'delete' item.pk %}">Delete</a></th>
    </tr>
    {% endfor %}
  </table>
</body>
</html>

3)DetailView

helloworld/templates/detail.html

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <title>Detail</title>
</head>
<body>
<h1>Detail</h1>
<table border="1">
  <tr>
    <th>no</th>
    <th>name</th>
    <th>modified_at</th>
    <th>created_at</th>
  </tr>
  <tr>
    <td>{{ object.no }}</td>
    <td>{{ object.name }}</td>
    <td>{{ object.modified_at }}</td>
    <td>{{ object.created_at }}</td>
  </tr>
</table>
</body>
</html>

4)DeleteView

helloworld/templates/delete.html

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <title>Delete</title>
</head>
<body>
<h1>Delete</h1>
<form method="post">
  {% csrf_token %}
  <table border="1">
    <tr>
      <th>no</th>
      <th>name</th>
      <th>modified_at</th>
      <th>created_at</th>
    </tr>
    <tr>
      <td>{{ object.no }}</td>
      <td>{{ object.name }}</td>
      <td>{{ object.modified_at }}</td>
      <td>{{ object.created_at }}</td>
    </tr>
  </table>
  <input type="submit" value="Delete">
</form>
</body>
</html>

5)UpdateView

helloworld/templates/update.html

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <title>Update</title>
</head>
<body>
<h1>Update</h1>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Update">
</form>
</body>
</html>

動作確認

~~~~
python ./helloworld/manage.py runserver
~~~~
などで、サーバを起動した状態で
ブラウザで以下のURLにアクセスする
 => 管理画面で登録したデータが表示されるはず

http://127.0.0.1:8000/helloworldapp/list

関連記事

Django ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2022/08/07/121017
Django ~ 基本編 / Class-based View ~
https://dk521123.hatenablog.com/entry/2022/08/08/140619
Django ~ 基本編 / アプリ ~
https://dk521123.hatenablog.com/entry/2022/08/09/092941