8
13

More than 3 years have passed since last update.

PythonのDjangoで最初のWebページ作り

Last updated at Posted at 2021-08-08

djangoのコマンドの覚書というかコピペ用台紙です。
何度やっても手順が覚えられなかったので、Qiitaの記事にしながらやっていきます。

自分用としては再現のための、コマンドのコピペテンプレートです。
読んでもらう方には、読むだけでコマンドや画像で動作がイメージできるように意識していきます。

前提

Ubuntu20.04。
python3は初めからインストールされています。
pipは途中でインストールされてないよって言われます。
プログラミング初心者の勉強用メモで、たくさんコピペさせていただいていますので、わかってない部分もあります。

クラスベースViewが難しかったため、関数ベースViewで書いてます。

仮想環境を用意

Pythonなので仮想環境(pythonライブラリの保存場所)を作ります。
今回はvirtualenvを使います。

$ sudo apt install python3-pip
$ pip3 install virtualenv

プロジェクトフォルダを作ってライブラリの保存場所を作ります。

$ mkdir testsite
$ cd testsite
$ virtualenv virtualenv

ライブラリの依存関係を再現できるようにするために、空のrequirement.txtを作っておきます。

$ touch requirement.txt

ファイル数は必要最小限です。
ディレクトリ構造は以下になります。

testsite
├── virtualenv
└── requirements.txt

仮想環境でインストール

仮想環境のvirtualenvにDjangoを入れていくため、仮想環境を起動させます。
これを忘れてローカル環境に入れて汚してしまうので、このために記事にしたところがあります。

ドット(.)と覚えていつも忘れてしまっていたので、sourceで覚えておきます。
現在のシェル(.)で仮想環境の実行です。

$ . virtualenv/bin/activate    # source virtualenv/bin/activate
(virtualenv)MyName@MyPC:~/testsite$ 

となれば仮想環境に入っています。
試しにpip3 listをするとライブラリの存在がない状態かと思います。

$ pip3 list

pipでライブラリをインストールしていきます。
version指定をしないと今はDjango3.X系が入りますが、2.2系で行きます。

$ pip3 install Django==2.2.24

とりあえず初心者なので、ここでrequirement.txtに練習をかねて書き込みます。

$ pip3 freeze -l > requirement.txt
$ vi requirement.txt
requirement.txt
Django==2.2.24
pytz==2021.1
sqlparse==0.4.1

プロジェクトの作成

プロジェクトフォルダは最初に作ってありますので、そこにDjangoのコードを生成します。
公式チュートリアルの作成方法では、プロジェクトフォルダ名と設定ディレクトリ名が同じになってしまいわかりずらいため、わかりやすい構成として、設定ディレクトリをconfigとする構成が用いられているようです

configという名前で設定ディレクトリを作成、現在のディレクトリ(.)をプロジェクトフォルダとするオプションで作成します。

$ django-admin startproject config .

configフォルダとmanage.pyができました。

testsite
├── config
├── virtualenv
├── manage.py
└── requirements.txt

これでひとまずは起動できますので、初心者的にはここで起動しておきます、、、

$ python3 manage.py runserver

が、ターミナル上で、
サーバー起動テスト.png
と、赤文字でエラーっぽいものが出ます。指示には従いません。
Django公式推奨通り、カスタムユーザーを作ってからmigrateしますので、起動確認で喜んでみただけです。

Django起動画面.png

英語なので日本語に変えます。

config/settings.py
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'

認証・認可機能の作成

Djangoでは使わなくても面倒でも先にカスタムユーザーを作ることが推奨されているようです。
Pythonというとまず仮想環境を作らされるお作法と近いかもしれません。
カスタムユーザーを作るとなると認可認証アプリを作ることにります。
便利な管理画面が最初からついてくることが原因で、あとから変なエラーがでたりするそうです。

もっと簡単っぽいやり方を紹介してくれている人もいます
カスタムユーザーモデルを作成する
今回は面倒そうでしたが、準公式とも言えそうなLearnDjango.comから拝借しました
Django Best Practices: Custom User Model

manage.pyでapp作成

Djangoでは機能をappという単位で呼ぶそうです。
標準の認証認可の機能を上書きするための、認証認可の機能をaccountsという名前で作っていきます。

$ python3 manage.py startapp accounts

プロジェクト設定ファイルへ読み込み

settings.pyのINSTALLED_APPSの末尾に、自分が作成したaccountsアプリを読み込ませる設定を書きます。
startappでできたファイルの中にapps.pyがあり、その中でクラスが定義されているので、そのクラスの読み込みです。

accounts/apps.py
from django.apps import AppConfig


class AccountsConfig(AppConfig):
    name = 'accounts'

↓このクラスを書き写して追加

config/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # manage.pyで作成した認証認可アプリ
    'accounts.apps.AccountsConfig',  # 追加
]

上から順番に読まれるそうなので、自分のアプリ(機能)は一番下に書くのがいいのかなぁと思っています。

カスタムユーザーの作成

作成はしますが、何もしません。passします;

accounts.models.py
from django.contrib.auth.models import AbstractUser
from django.db import models

class CustomUser(AbstractUser):
    pass

    def __str__(self):
        return self.username

認証ユーザーの上書き
startappで作ったaccountsのCustomUserクラスはmodels.pyにありますが、accounts.models.CustomUserとは書かないことに注意です。
settings.pyの末尾にでもコメントを添えて書き加えます。

config/settings.py
# 管理画面認証ユーザーの設定
AUTH_USER_MODEL = 'accounts.CustomUser'

ユーザー追加、登録フォームの上書き

管理画面とかで使われてるそうなので、怖いので従います。

$ touch accounts/forms.py
accounts/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'email')

class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'email')

管理画面への登録

モデル自体とフォームの登録と、画面表示の設定です。

accounts/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import CustomUser

class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ['email', 'username',]

admin.site.register(CustomUser, CustomUserAdmin)

データベースへの登録

$ python3 manage.py makemigrations accounts
$ python3 manage.py migrate

やっとmigrateできました。
migrateをしたので、db.sqlite3が作成されていますので、見てみます。

testsite
├── accounts
├── config
├── db.sqlite3
├── manage.py
├── requirements.txt
└── virtualenv

少しずつファイルが増えてきました。

ページ表示機能の作成

ここでやっと本題の最初のWebページ作りになります。
複数形だとかapp.appsになってややこしいだとか命名規則とかわかりませんが、appで作ります。

startapp

$ python3 manage.py startapp app
testsite
├── accounts
├── app
├── config
├── db.sqlite3
├── manage.py
├── requirements.txt
└── virtualenv
config/settings.py
INSTALLED_APPS = [
    ...,
    # manage.pyで作成した認証認可app
    'accounts.apps.AccountsConfig',   
    # manage.pyで作成したページ表示app # 追加
    'app.apps.AppConfig',          # 追加
]

設定

MVCと同じようにDjangoのMTVモデルでも、1つのファイルでは表示されません。
3つのファイルをいじってページを作成していきます。
URLにアクセスされたら → サーバー処理 → HTMLを返す順序でユーザーに表示されます。
urls.pyviews.pyHTMLファイルの順で作っていくのがわかりやすいかもしれません。

が、セッティングがまだ終わっていません。

テンプレートの読み込み先の指定

ディレクトリ直下にtemplatesというディレクトリを作ります。

$ mkdir templates

settings.pyTEMPLATESDIRSリストに今作ったテンプレートの場所を教えます。

config/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],  # ディレクトリ直下のtemplatesフォルダ
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

設定ファイルへのルーティング

アクセスはconfig.pyのurls.pyにしか来ない設定になっています。
これからappの中にurls.pyを作りますので、先に読み込ませる設定だけ書きます。

config/settings.py
from django.contrib import admin
from django.urls import path
from django.urls import include  # 追加

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(app.urls)),  # rootパスにmanage.pyで作成したapp内のurls.pyをincludeする。
]

urls.pyは今から作ります。

urls.pyの作成

includeするurlsを作って書いていきます。

touch app/urls.py
app/urls.py
urlpatterns = []

これで、空のままですが、読み込み設定はできました。

ページ作成

3つのファイルを一気に作ってHTMLを表示していきます。
先ほどの空のurlsviewstop関数を見るよう指示していきます。

app/urls.py
from django.urls import path
from app import views

urlpatterns = [
    path('', views.top, name='top'),
]

viewsにはtop関数を用意します。
top関数templates内のapp/top.htmlを参照します。

app/views.py
from django.shortcuts import render

def top(request):
    context = {}
    return render(request, 'app/top.html', context)
mkdir templates/app
touch templates/app/top.html 
templates/app/top.html
<h1>top.htmlのページ</h1>

DjangoTopPage2.png
表示できました。

BootStrapを導入してきれいなトップページを作ってみたいと思います。

BootStrapの導入

$ pip3 install django-bootstrap4
config/settings.py
INSTALLED_APPS = [
    ..., 
    # Bootstrapの導入
    'bootstrap4',
]

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ...,
            ],
            # Bootstrapの導入                            # 追加
            'builtins': [                               # 追加
                'bootstrap4.templatetags.bootstrap4'],  # 追加
        },
    },
]
template/app/top.html
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
<div class="jumbotron">
  <h1 class="display-4">Hello, world!</h1>
  <p class="lead">This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
  <hr class="my-4">
  <p>It uses utility classes for typography and spacing to space content out within the larger container.</p>
  <p class="lead">
    <a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a>
  </p>
</div>

DjangoTopPage3.png
実際コードがどのように変換されるかと言うと、

localhost
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" rel="stylesheet">
<script crossorigin="anonymous" integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script crossorigin="anonymous" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"></script>

CDNで取り込まれているだけでした。

とりあえずこれも依存関係として保存して

$ pip3 freeze -l > requirements.txt
$ cat requirements.txt 
beautifulsoup4==4.9.3
Django==2.2.24
django-bootstrap4==3.0.1
pytz==2021.1
soupsieve==2.2.1
sqlparse==0.4.1

参考にしたもの

8
13
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
8
13