0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Djangoプロトタイプのすゝめ

自分がまだ扱ったことのないフレームワークや言語を習得する際、以下のような手順を踏むべきだと考えています。

  1. テキストの解説を見ながらコードを模写する
  2. (チョー)簡単なアプリを作ってみる
  3. (ちゃんとした)アプリを作ってみる
  4. 繰り返し使う
  5. 気づいたら習得している

この記事では2.を中心的に取り上げます。

さて、何から始めたらよいのか

テキストを模写しているときはテキストの通りに進めたら、いつの間にか1つの機能が完成している(?!)という状況でした。
ここで、何から始めればいいの?ってなると思います。
まずは最初のステップについて説明します。

まずは何を作るか

ここでは、(チョー)簡単なアプリを作ります。
(習得していない状態でいきなり本格的なアプリを作ろうとすると詰みます)

(チョー)簡単なアプリとは...?
どのアプリでも(ほぼ)必ずあるものとは?

それは... CRUD操作ができること
です!

これを持つアプリとして以下のようなものがあります。

  • ブログ
  • タスク管理アプリ
  • ミニSNS

ということで、今回はブログを作ってみます

環境構築をする

今回はDockerを使って環境構築をしていきます。
プロジェクトフォルダを作成して、そのフォルダに移動しましょう。

プロジェクトフォルダ直下に以下のファイルを追加します。

FROM python:3.11
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ADD . /code/
requirements.txt
Django == 4.2.2
psycopg2-binary
django-environ
docker-compose.yml
version: "3"

services:
  db:
    image: postgres
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
  django:
    build:
      context: .
      dockerfile: Dockerfile
    command: python3 manage.py runserver 0.0.0.0:8000
    container_name: django
    env_file:
      - .env
    volumes:
      - ./django_app:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

volumes:
  postgres_data:
.env
POSTGRES_DB: "[データベース名]"
POSTGRES_USER: "[データベースのユーザ名(管理者)]"
POSTGRES_PASSWORD: "[データベースのパスワード]"

今後のアプリ開発ではGit管理をするので、それも意識して.envファイルを作成します。
プロジェクトフォルダに移動して以下のコマンドを実行しましょう.

コマンドを実行するときは、そのコマンドの意味を理解してから実行するようにしましょう。

以下のコマンドはプロジェクト名もそのまま記述しています。

docker-compose build
docker-compose django django-admin startproject django_app

アプリのひな形を作る

以下のコマンドを実行してアプリのひな形を作成しましょう

docker-compose run django python manage.py startapp blog

アプリを作ってみる

環境構築は上の解説を参考にしてください。
((私のように)環境構築であまり詰まってほしくはない...)
Django以外のアプリ開発経験がある方は挑戦してみると色々学ぶことができます

さて、今回作成するアプリの概要を説明します。
コード自体は最後に載せるので、まずは挑戦してみてください

要件

作るもの

  • ブログ
    (といっても、記事の編集と削除は省きます)

手順

  1. DBのことは考えず、views.pyからtemplateファイルに値を渡してみましょう
  2. models.pyで、テーブルを定義しましょう(マイグレーションもお忘れなく)
  3. DBから値を取得してtemplateファイルに値を渡しましょう
最終的なファイルたち
index.html
<!DOCTYPE html>
<html>
  <head>
    <title>{{ page_title }}</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container">
      <h1 class="my-4">{{ page_title }}</h1>
      <a href="{% url "create" %}" class="btn btn-success mb-4">投稿する</a>
      {% for post in posts %}
      <div class="list-group">
        <a
          href="{% url 'detail' post.id %}"
          class="list-group-item list-group-item-action"
        >
          <h5 class="mb-1">{{ post.title }}</h5>
          <small class="text-muted">{{ post.username }}</small>
          <p class="mb-1">{{ post.text }}</p>
        </a>
      </div>
      {% endfor %}
    </div>
  </body>
</html>
create.html
<!-- blog/templates/blog/create.html -->
<!DOCTYPE html>
<html>
  <head>
    <title>{{ page_title }}</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container">
      <h1 class="my-4">Create a New Blog Post</h1>
      <form method="post" action="{% url "create" %}">
        {% csrf_token %}
        <div class="form-group">
          <label for="title">Title:</label>
          <input
            type="text"
            class="form-control"
            id="title"
            name="title"
            required
          />
        </div>
        <div class="form-group">
          <label for="username">Username:</label>
          <input
            type="text"
            class="form-control"
            id="username"
            name="username"
            required
          />
        </div>
        <div class="form-group">
          <label for="text">Content:</label>
          <textarea
            class="form-control"
            id="content"
            name="text"
            rows="5"
            required
          ></textarea>
        </div>
        <button type="submit" class="btn btn-primary">Submit</button>
      </form>
    </div>
  </body>
</html>
detail.html
<!-- blog/templates/blog/show.html -->
<!DOCTYPE html>
<html>
  <head>
    <title>{{ page_title }}</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
      rel="stylesheet"
    />
  </head>
  <body>
    <div class="container">
      <h1 class="my-4">{{ post.title }}</h1>
      <p class="text-muted">{{ post.username }}</p>
      <p>{{ post.text }}</p>
      <a href="{% url 'index' %}" class="btn btn-primary">全件表示に戻る</a>
    </div>
  </body>
</html>
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .forms import PostForm
from .models import Post

def index(request):
    posts = Post.objects.all()
    params = {
        'page_title': '記事一覧',
        'posts': posts,
    }
    return render(request, 'blog/index.html', params)

def detail(request, post_id):
    post = Post.objects.get(id=post_id)
    params = {
        'page_title': '記事詳細',
        'post': post,
    }
    return render(request, 'blog/detail.html', params)

def create(request):
    if (request.method == 'POST'):
        obj = Post()
        post = PostForm(request.POST, instance=obj)
        post.save()
        return redirect(to='/blog')
    params = {
        'page_title': '投稿する',
        'form': PostForm(),
    }
    return render(request, 'blog/create.html', params)
forms.py
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['username', 'title', 'text']
        labels = {
            'title': '記事タイトル',
            'text': '記事本文',
        }
        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'text': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
        }
models.py
from django.db import models

class Post(models.Model):
    username = models.CharField(max_length=255, default='default_name')
    title = models.CharField(max_length=100)
    text = models.TextField(max_length=300, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
blog/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:post_id>', views.detail, name='detail'),
    path('create', views.create, name='create'),
    path('edit', views.edit, name='edit'),
]
django_app/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls')),
]
settings.py
# 変更箇所のみ記載
import environ

env = environ.Env()
environ.Env.read_env()

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
]
POSTGRES_DB = env('POSTGRES_DB')
POSTGRES_USER = env('POSTGRES_USER')
POSTGRES_PASSWORD = env('POSTGRES_PASSWORD')
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': POSTGRES_DB,
        'PASSWORD': POSTGRES_PASSWORD,
        'USER': POSTGRES_USER,
        'HOST': 'db',
    }
}

おわりに

無事、ブログアプリ完成したでしょうか?
環境や私の不備の関係でコードが思うように動かなかったということがあるかもしれません...。
コードが動かないときのtipsを記しておきます

  • コンソールに表示されているエラー文を読む
    (このコマンドを実行しろ!とかの文章が表示される場合があります)

  • エラー文を検索してみる
    Qiitaとかいろんなサイトで、同じところで詰まっている方がいるかもしれません。

  • ChatGPTに相談してみる
    ある程度は相談に乗ってくれます。ChatGPTの文章に含まれるキーワードを使って検索してみるといいかもしれません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?