【初めてのDjango Web開発】モデルと紐付いた投稿フォームとCSSの適用
PythonのフレームワークであるDjangoでは、modelで定義したフィールドをそのまま使って自動生成されるフォームを簡単に作ることができます。その作成方法を初心者向けにメモしておきます。ただそれだけでもとても便利ですが、さらにCSSを適用して、見た目も良くしてみます。
使用しているDjango version は4.2.16です。
目次
models.pyの作成
投稿データをsqlite3で保存するためのテーブルを定義します。
尚フォルダ構成はこれに限定されるものではありませんので、ご自分の環境に合わせて参考にしてください。
models.py
fumProj/myblog/models.py
from django.db import models
# Create your models here.
class Post(models.Model):
id=models.AutoField(primary_key=True, verbose_name="ID")
title=models.CharField(max_length=128, verbose_name="タイトル")
body = models.TextField(max_length=255, verbose_name="本文")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="作成日")
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新日")
def __str__(self):
return self.title
forms.pyの作成
models.pyと同じ階層にforms.pyを作成し、django.forms.ModelFormクラスを継承させます。
forms.py
fumProj/myblog/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post # ←紐付くモデル名
fields = ["title", "body"] # ←紐付くフィールド名
Metaクラスのクラス変数(model)でPostモデルと紐づけるだけです。
『model = Post」』でPostモデルと紐付かせ、
『fields = ["title", "body"] 』で紐付かせたいフィールドをリスト配列で複数記述します。
urls.pyとviews.pyの作成
作成したアプリ毎にurls.pyを作成すると、複数のアプリを切り替えることができます。
urls.py
fumProj/myblog/urls.py
from django.urls import path
from . import views
# blogアプリ用urlpatterns
urlpatterns = [
path("", views.index, name="post_index"),
path("create/", views.post_create, name="post_create"),
]
fumProj/fumProj/urls.py
from django.contrib import admin
from django.urls import path, include
# project全体のurlpatterns
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include("myblog.urls")),
]
views.py
fumProj/myblog/views.py
from django.shortcuts import render, redirect
from django.views import View
from .forms import PostForm
# 新規投稿用(classベースview)
class PostCreateView(View):
def get(self, request):
form=PostForm() # ← # PostForm のインスタンスを生成
# "form"というkeyでformインスタンスを渡します。
return render(request, "myblog/postCreateform.html", {"form": form})
def post(self, request):
form = PostForm(request.POST)
if form.is_valid(): # ←validationがOKなら
form.save() # ←保存
return redirect("post_index") # ←投稿一覧にリダイレクト
return render(request, 'myblog/postCreateform.html', {"form": form})
post_create = PostCreateView.as_view()
base.htmlとpostCreateform.htmlの作成
base.html
fumProj/myblog/templates/myblog/base.html
<!DOCTYPE html>
{% load static %}
<html lang="ja">
<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>myBlog | 初めてのdjango</title>
<link rel="stylesheet" href="{% static '/css/common.css' %}">
</head>
<body>
<div class="container" >
{% block content %} {% endblock %}
</div>
<footer><small>by Django ver 4.2.16</small></footer>
</body>
</html>
postCreateform.html
fumProj/myblog/templates/myblog/postCreateform.html
{% extends "myblog/base.html" %}
{% load static %}
{% block content %}
<h2>新規作成画面</h2>
<form class="create_form" action="" method="post">
{% csrf_token %}
{{ form.as_p }} # ←これを記載するだけ自動で展開される!!
<button type="submit" class="submit-btn">登録</button>
</form>
<a class="left_pos" href="{% url "post_index" %}">トップ画面に戻る</a>
{% endblock %}
form変数にはフィールドの情報が格納されており、<form>タグの中に{{ form }}とすれば、HTMLに自動で展開されます。
{{ form.as_p }}とすれば、<p>タグで各フィールドが囲まれて展開されます。.as_p以外にも.as_tableとすればテーブル形式で、.as_ulとすればリスト形式で表示されます。
しかし、このままだと各フィールドは整頓されていません。
改善前の投稿フォーム
{{ form.as_p }}で展開した場合の投稿フォームです。
改善前の投稿フォーム
これでも十分使えますが、右側の余白が少し気になります。
このHTMLはどうなっているのか、「ページのソースの表示」で確認してみると。
ソースの表示
<form class="create_form" action="" method="post">
<input type="hidden" name="csrfmiddlewaretoken"
value="J6oqbh2pj2ku9zbCMoVeB0JH1IrOlrBYi3ZQ0EJg1ERSfJjtaRwexHrBvFssQmR6">
<p>
<label for="id_title">タイトル:</label>
<input type="text" name="title" maxlength="128"
required id="id_title">
</p>
<p>
<label for="id_body">本文:</label>
<textarea name="body" cols="40" rows="10"
maxlength="255" required id="id_body"></textarea>
</p>
<button type="submit" class="submit-btn">登録</button>
</form>
各フィールドが<p>タグで囲まれており、タイトルにはid="id_title"、本文にはid="id_body"とidが付けられていました。
cssを適用出来そうですので、cssでフォームを少し改善してみます。
改善後の投稿フォーム
改善後の投稿フォーム
右側の余白も消え、広く使えそうです。
適用したcssは次の通りです。
style(common.css)
.create_form p{
display: flex;
justify-content: space-between;
}
.create_form #id_title,
.create_form #id_body{
flex: 1;
padding: 4px;
margin: 0 8px;
box-sizing: border-box;
}
.create_form p > label{
display: inline-block;
width: 80px;
text-align: right;
}
{{ form.as_p }}と1行書くだけで自動でできるので、このままでしか使えないのかと思っていたら、少しぐらいなら自分の好みに合わせて変更できそうです。
以上です。😁