DJagno#1 とりあえず投稿フォームを作成する
Djangoを弄って1ヶ月くらいになります。
MVCとかMTVモデルとか出てきますが概念の理解に努めるより、コピペでも実際にコードを書いて動かしてみた方が早い気がします。
その点Djangoでフォームを作成することは、MTVモデルの理解にもってこいなのではないかと思ったので今回書かせていただきました。
【目次】
プロジェクトとアプリの作成
$ django-admin startproject mysite $ python manage.py startapp form
任意の名前でプロジェクト→アプリの順にプリセットを作成しましょう。
環境構築~アプリ作成までは以前の記事で解説しているので、こちらご参照いただければと思います。
今回はmysiteというプロジェクトを作成して、その中にformという名前のアプリを作成しました。
編集するファイル
簡単なフォームを作成して動作させるために必要なファイルを先に列挙しておきます。
mysite │ asgi.py │ settings.py │ urls.py │ wsgi.py │ __init__.py │ └─__pycache__
プロジェクトフォルダの以下ファイルが編集対象です。
setting.py
urls.py
■アプリ
models.py
views.py
url.py
プロジェクトファイルの編集
setting.py
setting.pyを開いてINSTALLED_APPSの項目に先ほど作成したformアプリを記述します。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', #追加 'form', ]
このように記述しておかなければユーザーが作成したアプリが認識されません。
ついでに同ファイルのTEMPLATESという項目も御覧ください。
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR, 'templates'], 'APP_DIRS': True, #…(省略) }, ]
DIRSの箇所は初期設定で空白([])となっているので「BASE_DIR, 'templates'」と足しておきましょう。
これはテンプレートファイルを呼び出すときにどこを捜索するか指定するもので、空白だと捜索が行われません。
後ほどプロジェクトフォルダのディレクトリに「templates」という名前でテンプレートフォルダを作成します。
urls.py(アプリ間ルーティング)
setting.pyと同フォルダにあるurls.pyを開いてください。
ここではルーティングを行います。
例えばexample.com/formapp/form.htmlというURLにアクセスしたとき、formアプリフォルダを参照するように設定する必要があります。
from django.urls import path , include urlpatterns = [ path('admin/', admin.site.urls), path('formapp/', include('form.urls')), ]
まずfrom django.urls import pathとなっている場合はincludeを追加してください。
ちなみにこの「from ~ import XX 」というのは「~という場所からXX関数を呼び出して使用可能にする」記述です。
そしてurlpatternsにpath('formapp/', include('form.urls')),を追加します。
example.com/formapp/にアクセスするとそれ以下のディレクトリはformアプリ内のurl.confに処理を任せるようになります。
このように特定のディレクトリで処理に用いるurl.confを変更可能にするのがinclude関数です。
アプリディレクトリ内の編集
modelsの記述
modelとはデータベースを定義するものです。
「投稿フォームから送信された内容を保存する箱を作る」
もしデータベースが分からなくてもこのようにイメージ持ってもらえればと思います。
from django.db import models class PostModel(models.Model): title = models.CharField(max_length=50) content = models.TextField()
それではmodels.pyを開いてください。
今回はタイトルと内容だけの投稿フォームを作成予定なので、上記のようなクラスを作成しました。
クラス名のあとに続く(models.Model)とは継承元クラスを指しております。
viewsの記述
MTVモデルのMとTまで記述できました。
あとはviewファイルです。
form\views.pyを開いて以下のように記述します。
from django.views.generic import ListView, CreateView from django.urls import reverse_lazy from .models import PostModel class ListClass(ListView): template_name = 'list.html' model = PostModel class FormClass(CreateView): template_name = 'form.html' model = PostModel fields = ('title','content') success_url = reverse_lazy('list')
他より長くなりますが1個1個説明していきます。
まずインポートした関数について。
from django.views.generic import ListView, CreateView
まず新規投稿においてはCreateView、投稿一覧表示にはListViewという汎用ビューを使用します。
from django.urls import reverse_lazy
投稿後にリダイレクト先を指定できます。
from .models import PostModel
models.pyで作成したモデルも読み込んでおかないとデータの受け渡しができません。
次に作成したクラスについて。
class ListClass(ListView):
汎用ビューを使用する場合は継承します。
template_name = 'list.html'
viewファイルを裏側で処理する部分だとすれば、対応する表側のテンプレートファイルを指定する必要あり。
success_url = reverse_lazy('list')
投稿に成功(データベースへの保存)したときの遷移先を指定します。
urls.pyの記述(アプリ内ルーティング)
最後にアプリファイル内のurls.pyを設定します。
プロジェクト(mysite)内のフォルダにあるurls.pyでは、example.com/formapp/以下にアクセスされた場合にform\urls.pyに振る設定を行いました。
こちらのurls.pyは自分で作成する必要があるので、form\urls.pyに作成しましょう。
from django.urls import path from .views import FormClass, ListClass urlpatterns = [ path('form/', FormClass.as_view(), name='form'), path('list/', ListClass.as_view(), name='list'), ]
任意のパスを設定し、viewに記述されたどのクラスと対応するのか記述します。
記述したクラスについてはimport関数で呼び出しておく必要ありです。
ちなみにviews.pyでsuccess_url = reverse_lazy('list')と出てきましたが、ここでname='list'と記述することによって名前で呼び出せるようになっていたのです。
templateの記述
urls.pyの項目でテンプレートファイルの参照先にtemplatesフォルダを指定しました。
以下のようにmysite\templetesを作成し、テンプレートファイルform.htmlとlist.htmlを作成します。
mysite │ manage.py │ ├─form │ │ admin.py │ │ apps.py │ │ models.py │ │ tests.py │ │ views.py │ │ __init__.py │ │ │ └─migrations │ __init__.py │ ├─templates │ list.html │ form.html │ └─mysite │ asgi.py │ settings.py │ urls.py │ wsgi.py │ __init__.py │ └─__pycache__
form.htmlに投稿画面、list.htmlに投稿一覧の内容をそれぞれ記述します。
投稿画面
作成したform.htmlをエディタで開き以下のように記述してみましょう。
<form method="POST"> {% csrf_token %} <p>タイトル:<input type="text" name="title"></p> <p>内容:<input type="text" name="content"></p> <input type="submit" value="投稿する"> </form>
htmlの話になってしまうのですが、formタグと呼ばれるものを記述しました。
formタグの中にinput typeなどの要素を配置して簡単に入力フォームを作成できます。
{% csrf_token %}の記述は、CSRF(クロスサイトリクエストフォージェリ)という脆弱性を狙った攻撃を防ぐセキュリティ対策の記述です。
余談ですがmethodにはPOSTやGETが存在します。前者はDBの変更を伴うもの、後者は読み取り専用で使われることが多いようです。
投稿一覧
次にlist.htmlを以下のように編集しましょう。
<div class="container"> {% for post in object_list %} <div class="post"> <p>タイトル:{{ post.title }}</p> <p>内容:{{ post.contant }}</p> <p>--------------------</p> </div> {% endfor %} </div>
何が書かれてあるかというと「POSTモデルから全投稿のタイトルと内容を表示する」というものです。
djangoではデータベースのデータを{{ }}で囲んで記述することで、テンプレートに表示させることが可能です。
マイグレーションを行う
さて、必要なファイルは揃えたのであとはプログラムを実行します。
その前にマイグレーション作業を行わなければなりません。
マイグレーションとは簡単に言うとモデルの変更などをデータベースに反映させることです。
$ python manage.py makemigrations
$ python manage.py migrate
ローカルサーバーでテストする前に上記2つのコマンドを実行しておけば大丈夫です。
ローカルサーバー起動
$ python manage.py runserver
localhostを実行しhttp://127.0.0.1:8000/formapp/formへアクセスします。
(今回はトップページを設定していないので)
するとこのようなフォームが表示されるのではないでしょうか。
投稿するとこのように投稿一覧画面に遷移するはずです。
=====
こんな感じでしばらくDjangoに関する記事を上げていければと思います。
どなたかの参考にでもなれば幸いです。