👋

Django Crud Example

2022/11/02に公開

Django + Dockerよく使うコマンド(メモ)

# バージョン確認
docker-compose exec web ./manage.py --version

# プロジェクトをスタート
docker-compose up -d --build
docker-compose run web django-admin.py startproject 【project_name】 .

# 全て削除
・(コンテナを止めて、ネットワーク、ボリュームもイメージを削除)
docker-compose down --rmi all --volumes

# アプリ作成
docker-compose run --rm web django-admin startapp app_name

# マイグレーション
docker-compose run --rm web python3 manage.py makemigrations

# マイグレイト
docker-compose run --rm web python3 manage.py migrate

# クリエイトユーザー
・管理画面にログインする際に必要。
docker-compose run --rm web python3 manage.py createsuperuser

# 古いネットワークを取り除く
docker system prune -a

# コンテナの停止
docker-compose down -v

開発環境構築

https://zenn.dev/toccaduong/articles/901868e8710896

アプリ追加

docker-compose run --rm web django-admin startapp crud_example

作成が完了すると、下記のようなファイル構造が生成される。

アプリ設定

settings.pyに編集

INSTALLED_APPS = [
...
    'crud_example',
]

モデルとテーブルの作成

テーブル定義に合わせたモデルを作成
crud_example/models.py編集

from django.db import models

# Create your models here.
class CrudExample(models.Model):
    name = models.CharField(max_length=200)
    age = models.IntegerField()
    job = models.CharField(max_length=200)

    def __str__(self):
        return self.name
        
    class Meta:
        db_table = "cruds_example"

マイグレーションファイルを作成

$ docker-compose run --rm web python3 manage.py makemigrations crud_example
Creating app_web_run ... done
Migrations for 'crud_example':
  crud_example/migrations/0001_initial.py
    - Create model CrudsExample
$

以下のファイルが自動で作成される
\migrations\0001_initial.py

# Generated by Django 3.2.12 on 2022-10-31 06:55

from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='CrudExample',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=200)),
                ('age', models.IntegerField()),
                ('job', models.CharField(max_length=200)),
            ],
            options={
                'db_table': 'cruds_example',
            },
        ),
    ]

テーブルを作成

$ docker-compose run --rm web python3 manage.py migrate
Creating app_web_run ... done
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, crud_example, sessions
Running migrations:
  Applying crud_example.0001_initial... OK
$

確認

表示や機能設定

\urls.pyの編集

~~~
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('crud_example.urls')),
]

crud_example/urlsファイル作成

touch crud_example/urls.py
from django.urls import path
from . import views

app_name = "App"

urlpatterns = [
    path('', views.List.as_view(), name='top'),
    path('create/', views.Create.as_view(), name='create'),
    path('update/<int:pk>/', views.Update.as_view(), name='update'),
    path('delete/<int:pk>/', views.Delete.as_view(), name='delete'),
]

crud_example/views.pyの編集

from django.shortcuts import render
from django.http import HttpResponse
from django.urls import reverse_lazy,reverse
from django.views.generic import (ListView,CreateView,UpdateView,DeleteView)

from . import models
# Create your views here.

class List(ListView):
    #テーブル連携
    model = models.CrudExample
    #レコード情報をテンプレートに渡すオブジェクト
    context_object_name = "lists"
    #テンプレートファイル連携
    template_name = "index.html"
    
class Create(CreateView):
    #テーブル連携
    model = models.CrudExample
    #入力項目定義
    fields = ("name","age","job")
    #テンプレートファイル連携
    template_name = "create.html"
    #作成後のリダイレクト先
    success_url = reverse_lazy("App:top")
    
class Update(UpdateView):
    #テーブル連携
    model = models.CrudExample
    #入力項目定義
    fields = ("name","age","job")
    #テンプレートファイル連携
    template_name = "update.html"
    #作成後のリダイレクト先
    success_url = reverse_lazy("App:top")
    
class Delete(DeleteView):
    #テーブル連携
    model = models.CrudExample
    #削除後のリダイレクト先
    success_url = reverse_lazy("App:top")

テンプレートフォルダ

mkdir crud_example/templates

Navbar

touch crud_example/templates/nav.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}CRUD{% endblock title %}</title>
</head>
<body>
    <nav style="background-color: grey;">
        <h1>NavBar</h1>
    </nav>
    <div class="container">
        {% block content_block %}
        {% endblock %}
    </div>
</body>
</html>

トップ画面

touch crud_example/templates/index.html
{% extends "nav.html" %}

{% block content_block %}
    <h1>LIST</h1>
    <table border=1>
        <tr>
            <th>ID</th>
            <th>Name</th>
            <th>Age</th>
            <th>Job</th>
            <th>Action</th>
        </tr>
        {% for list in lists %}
        <tr>
            <td>{{ list.id }}</td>
            <td>{{ list.name }}</td>
            <td>{{ list.age }}</td>
            <td>{{ list.job }}</td>
            <td>
                <form method="POST" action="{% url 'App:delete' list.id %}">
                    {% csrf_token %}
                    <a href="{% url 'App:update' list.id %}">Edit</a>
                    <a href="" onclick="if (confirm('マジでっか?')){this.closest('form').submit();return false;} return false;">Delete</a>
                </form>
            </td>
        </tr>
        {% endfor %}
    </table>
    <div class="container">
        <p><a href="{% url 'App:create' %}">Add</a></p>
    </div>
{% endblock %}

登録画面

touch crud_example/templates/create.html
{% extends "nav.html" %}
{% block content_block %}
<h1>CREATE</h1>
<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" class='btn btn-primary' value="CREATE">
    <input type="button" value="BACK" onclick="location.href='{% url 'App:top' %}'">
</form>
{% endblock %}

編集画面

touch crud_example/templates/update.html
{% extends "nav.html" %}

{% block content_block %}
<h1>UPDATE</h1>
<form method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="UPDATE">
    <input type="button" value="BACK" onclick="location.href='{% url 'App:top' %}'">
</form>
{% endblock %}

終わり。

Enjoy.!!

Discussion