djangoを殆ど触ったことがない為、参考urlの内容を写経してみました
目次
- 参考url
- python仮想環境作成と、djangoのインストール
- django プロジェクトの作成
- 付属サーバによる接続確認
- 簡易アプリ作成 - その1. VIEW
- 簡易アプリ作成 - その2. MODEL
- 付属する管理ツール
- HTMLテンプレート
- DB変更 - CRUD
- 静的ファイル
参考url
python仮想環境作成と、djangoのインストール
$ cat /etc/redhat-release Red Hat Enterprise Linux release 9.1 (Plow) $ which python ~/.pyenv/shims/python $ python --version Python 3.9.14 $ pwd /home/end0tknr/proj $ python -m venv django $ source ./bin/activate $ pip install django : Successfully installed asgiref-3.6.0 django-4.1.7 sqlparse-0.4.3
django プロジェクトの作成
設定dir名がプロジェクト名となる為、一旦、 config という名でプロジェクト作成し、その後、名称変更
$ cd /home/end0tknr/proj/django $ django-admin startproject config $ mv config myproj $ cd myproj $ tree ├ config │ ├ asgi.py │ ├ settings.py │ ├ urls.py │ └ wsgi.py └ manage.py
付属サーバによる接続確認
vi config/settings.py
ALLOWED_HOSTS = ['*'] # old) ALLOWED_HOSTS = [] TIME_ZONE = 'Asia/Tokyo' # old) TIME_ZONE = 'UTC'
付属サーバ起動と、接続確認
$ python3 manage.py runserver 0.0.0.0:8080
上記を実行後、ブラウザでアクセスすると、以下が表示

簡易アプリ作成 - その1. VIEW
manage.py startapp $app_name
$ cd /home/end0tknr/proj/django/myproj $ python3 manage.py startapp books $ tree ├ books ## NEW │ ├ admin.py ## 〃 │ ├ apps.py ## 〃 │ ├ migrations/ ## 〃 │ ├ models.py ## 〃 │ ├ tests.py ## 〃 │ └ views.py ## 〃 ├ config │ ├ asgi.py │ ├ settings.py │ ├ urls.py │ └ wsgi.py ├ db.sqlite3 └ manage.py
config/settings.py 修正
INSTALLED_APPS = [
'books', ## ADD
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
アプリ用ルーティング設定
config/urls.py 修正
from django.contrib import admin from django.urls import path, include ## ADD urlpatterns = [ path('admin/', admin.site.urls), path('books/', include('books.urls')), ## ADD ]
books/urls.py 追加
from django.urls import path from . import views # 名前空間:reverseメソッドやurlタグから # 「<名前空間名>:<名前空間内のname>」でurlで逆引きできる app_name = 'books' urlpatterns = [ path('', views.list_books, name='list_books' ), ]
books/views.py 変更
from django.shortcuts import render from django.http import HttpResponse def list_books(request): return HttpResponse("Hello world!")
付属サーバ起動と、動作確認
$ python3 manage.py runserver 0.0.0.0:8080
上記を実行後、http://localhost:8080/books/ へ、 ブラウザでアクセスすると、「Hello world!」と表示されれば、OK
簡易アプリ作成 - その2. MODEL
MODELクラス作成 - books/models.py の変更
from django.db import models class Book(models.Model): book_id = models.CharField(max_length=32) title = models.CharField(max_length=256) author = models.CharField(max_length=256) def __str__(self): return self.title
DBマイグレーション ファイル作成
$ python3 manage.py makemigrations
Migrations for 'books':
books/migrations/0001_initial.py
- Create model Book
$ less books/migrations/0001_initial.py
from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [] operations = [ migrations.CreateModel( name='Book', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('book_id',models.CharField(max_length=32)), ('title', models.CharField(max_length=256)), ('author', models.CharField(max_length=256)), ], ), ]
DBマイグレート実行
$ python3 manage.py migrate Operations to perform: Apply all migrations: admin, auth, books, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK 【略】 Applying books.0001_initial... OK Applying sessions.0001_initial... OK
DBスキーマ確認
$ python3 manage.py dbshell SQLite version 3.34.1 2021-01-20 14:10:07 sqlite> .tables auth_group books_book auth_group_permissions django_admin_log auth_permission django_content_type auth_user django_migrations auth_user_groups django_session auth_user_user_permissions sqlite> .schema books_book CREATE TABLE IF NOT EXISTS "books_book" ( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "book_id" varchar(32) NOT NULL, "title" varchar(256) NOT NULL, "author" varchar(256) NOT NULL );
付属する管理ツール
管理USER作成
$ python3 manage.py createsuperuser Username (leave blank to use 'end0tknr'): Email address: 【空でもOK】 Password: Password (again): Superuser created successfully.
管理対象MODEL追加 - books/admin.py の修正
from django.contrib import admin from .models import Book admin.site.register(Book)
管理ツールによるDB編集
$ python3 manage.py runserver 0.0.0.0:8080
上記を実行し、http://localhost:8080/admin/ へ、アクセスすると、 次のような画面が表示され、ログイン後、dbを編集できます



HTMLテンプレート
テンプレート用DIRの追加 - config/settings.py の修正
import os ## ADD TEMPLATES = [ {'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], ## CHANGE }]
テンプレート用DIRの追加 - mkdir templates
$ cd /home/end0tknr/proj/django/myproj mkdir -p templates mkdir -p templates/books $ tree ├ books │ ├ admin.py │ ├ apps.py │ ├ migrations │ │ └ 0001_initial.py │ ├ models.py │ ├ tests.py │ ├ urls.py │ └ views.py ├ config │ ├ asgi.py │ ├ settings.py │ ├ urls.py │ └ wsgi.py ├ db.sqlite3 ├ manage.py └ templates ## NEW └ books ## 〃
テンプレート ファイル作成
$ vi templates/layout.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>{{ title }}</title> </head> <body> <h1>{{ title }}</h1> {% block content %}{% endblock %} </body> </html>
$ vi templates/books/list_books.html
{% extends 'layout.html' %}
{% block content %}
<table>
<thead>
<tr>
<th>Book ID</th>
<th>Title</th>
<th>Author</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% if books %}
{% for book in books %}
<tr>
<td><a href="/books/{{ book.book_id }}">{{ book.book_id }}</a></td>
<td>{{ book.title }}</td>
<td>{{ book.author }}</td>
<td><a href="/books/{{ book.book_id }}/edit">[Edit]</a></td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan=4>No books.</td>
</tr>
{% endif %}
</tbody>
</table>
{% endblock %}
VIEWメソッドの追加 - books/views.py の変更
from django.shortcuts import render from django.http import HttpResponse from django.template import loader from .models import Book # def list_books(request): # return HttpResponse("Hello world!") def list_books(request): books = Book.objects.all() context = { 'title': 'List Books', 'books': books, } template = loader.get_template('books/list_books.html') return HttpResponse(template.render(context, request))
付属サーバによる動作確認
$ python3 manage.py runserver 0.0.0.0:8080
上記を実行後、http://localhost:8080/books/ へ、 ブラウザでアクセスすると、先程、管理ツールで登録したものが表示されます

DB変更 - CRUD
編集用URL追加 - books/urls.py
from django.urls import path from . import views # 名前空間:reverseメソッドやurlタグから # 「<名前空間名>:<名前空間内のname>」でurlで逆引きできる app_name = 'books' urlpatterns = [ path('', views.list_books, name='list_books' ), path('<str:book_id>', views.detail_book,name='detail_book'), path('<str:book_id>/edit',views.edit_book, name='edit_book' ), ## ADD ]
編集用テンプレート作成 - templates/books/edit_book.html
※ 以下にある「{% url 'books:edit_book' book.book_id %}」は、 「/books/1/edit」のように実体化されます。
{% extends 'layout.html' %}
{% block content %}
<form method="POST" action="{% url 'books:edit_book' book.book_id %}">
{% csrf_token %}
<input type="hidden" name="mode" value="{{ mode }}">
<table>
<tr>
<th>Book ID</th>
<td><input type="text" name="book_id" readonly value="{{ book.book_id }}"></td>
</tr>
<tr>
<th>Title</th>
<td><input type="text" name="title"
{% if mode != 'input' %}readonly{% endif %} value="{{ book.title }}"></td>
</tr>
<tr>
<th>Author</th>
<td><input type="text" name="author"
{% if mode != 'input' %}readonly{% endif %} value="{{ book.author }}"></td>
</tr>
</table>
<div class="basic-block">
{% if mode == 'input' %}
<button type="button" onclick="location.href='{% url 'books:list_books' %}'">Return</button>
<button type="submit">OK</button>
{% elif mode == 'confirm' %}
<button type="button" onclick="history.back()">Back</button>
<button type="submit">OK</button>
{% elif mode == 'result' %}
<button type="button" onclick="location.href='{% url 'books:list_books' %}'">Return</button>
{% endif %}
</div>
</form>
{% endblock %}
CRUD処理追加 - books/views.py
def edit_book(request, book_id): if request.method == 'GET': return edit_book_input(request, book_id) if request.method == 'POST': if request.POST['mode'] == 'input': return edit_book_confirm(request, book_id) if request.POST['mode'] == 'confirm': return edit_book_result(request, book_id) def edit_book_input(request, book_id): try: book = Book.objects.get(book_id=book_id) except Book.DoesNotExist: book = None context = { 'title': 'Edit Book(input)', 'mode': 'input', 'book': book, } template = loader.get_template('books/edit_book.html') return HttpResponse(template.render(context, request)) def edit_book_confirm(request, book_id): book = Book() book.book_id = request.POST['book_id'] book.title = request.POST['title'] book.author = request.POST['author'] context = { 'title': 'Edit Book(confirm)', 'mode': 'confirm', 'warning_message': 'Are you sure you want to save?', 'book': book, } template = loader.get_template('books/edit_book.html') return HttpResponse(template.render(context, request)) def edit_book_result(request, book_id): try: book = Book.objects.get(book_id=book_id) book.book_id = request.POST['book_id'] book.title = request.POST['title'] book.author = request.POST['author'] book.save() ## 保存 except Book.DoesNotExist: book = None context = { 'title': 'Edit Book(result)', 'mode': 'result', 'success_message': 'Success!', 'book': book, } template = loader.get_template('books/edit_book.html') return HttpResponse(template.render(context, request))
付属サーバによる動作確認
$ python3 manage.py runserver 0.0.0.0:8080
上記を実行後、http://localhost:8080/books/ へ、 アクセスすると、以下の画面で、DB変更を確認できます

静的ファイル
静的ファイル用DIR追加 - config/settings.py の変更
STATIC_URL = 'static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
静的ファイル用DIR追加 - mkdir static
$ cd /home/end0tknr/proj/django/myproj
$ mkdir -p static/js
$ mkdir -p static/css
$ mkdir -p static/images
$ tree
├ books
│ ├ admin.py
│ ├ apps.py
│ ├ migrations
│ │ └ 0001_initial.py
│ ├ models.py
│ ├ tests.py
│ ├ urls.py
│ └ views.py
├ config
│ ├ asgi.py
│ ├ settings.py
│ ├ urls.py
│ └ wsgi.py
├ db.sqlite3
├ manage.py
├ static ## NEW
│ ├ css ## 〃
│ ├ images ## 〃
│ └ js ## 〃
└ templates
├ books
│ └ list_books.html
└ layout.html
静的ファイルの作成
table { border-collapse: collapse; margin-bottom: .5rem; } table th, table td { border: 1px solid #999; padding: .1rem .3rem; } table th { background-color: #ddd; } button { line-height: 1.2rem; min-width: 6rem; }
$ vi templates/layout.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>{{ title }}</title> <link rel="stylesheet" href="/static/css/style.css"> <!--ADD--> </head> <body> <h1>{{ title }}</h1> {% block content %}{% endblock %} </body> </html>
付属サーバによる動作確認
$ python3 manage.py runserver 0.0.0.0:8080
上記を実行後、http://localhost:8080/books/ へ、 アクセスすると、以下が表示
