#ちょっとだけCSS
$mkdir static
$touch base.css
プロジェクト直下にstatic
ディレクトリを作り、その中にcssファイルを作成します。
staticは静的という意味で、静的なファイルを入れておくみたいです。
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
設定ファイルにこれを追加する。
{% load staticfiles %} ←これを追加
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
↓これを追加
<link rel="stylesheet" href="{% static 'base.css' %}">
<title>{% block page_title %}{% endblock %}</title>
</head>
これでcssが使えます。
ちょっとめんどくさいですね。
投稿を表示する機能を作る前にbaseのHTMLとCSSをヒョヒョイっと書いちゃいます。
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="{% static 'base.css' %}">
<title>{% block page_title %}{% endblock %}</title>
</head>
<body>
<nav>
<p class="site-name">Blog</p>
<ul>
<li><a href="{% url 'posts:index' %}">Top</a></li>
<li><a href="{% url 'posts:write' %}">Write</a></li>
</ul>
</nav>
<div class="title">
<h1>{% block title %}{% endblock %}</h1>
</div>
<hr>
<div class="content">
{% block content%}{% endblock %}
</div>
<hr>
</body>
</html>
html, body{
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
body, h1, hr {
margin: 0px;
}
a{
color: #e8e8e8;
}
nav p{
margin: 0px;
font-size: 30px;
}
nav{
padding: 10px 10px;
color: #e8e8e8;
background-color: #41a888;
}
nav .site-name{
display: inline-block;
}
nav ul{
margin: 0px;
padding: 0px;
float: right;
}
nav ul li{
padding: 10px;
display: inline-block;
}
.title{
margin: 21px 50px;
}
.content{
margin: 20px 50px;
}
view.py
とurls.py
に投稿を書く画面(write)を追加します。
class WriteView(View):
def get(self, request, *args, **kwargs):
return render(request, 'posts/write.html')
write = WriteView.as_view()
app_name = 'posts'
urlpatterns = [
path('', views.index, name='index'),
path('write/', views.write, name='write'), ←これを追加
]
そしたらこんな感じに整います。
投稿一覧画面(post)と投稿を書く画面(write)のどっちを先にやろうかな〜って考えたんですけど、投稿を書く画面(write)からやっちゃいます。
投稿作成画面
入力フォームを作成し、入力内容をデータベースに保存します。
流れ
- form.pyの作成
- views.pyの作成
- htmlの作成
まずはフォームだけ
$cd posts
$touch form.py
from django import forms
from .models import Posts
class WriteForm(forms.ModelForm):
class Meta:
#モデルを指定
model = Posts
#フォームとして表示したいカラムを指定
fields = ('text',)
from django.shortcuts import render
# Create your views here.
from django.views.generic import View
#form.pyからフォームをインポート
from .form import WriteForm
class IndexView(View):
def get(self,request, *args, **kwargs):
return render(request, 'posts/post.html')
index = IndexView.as_view()
class WriteView(View):
def get(self, request, *args, **kwargs):
#値付きでhtmlファイルに飛ぶ
return render(request, 'posts/write.html', {'form': WriteForm})
write = WriteView.as_view()
{% extends "base.html" %}
{% block page_title %}Write{% endblock %}
{% block title %}Write{% endblock %}
{% block content %}
<form method="post" action="{% url 'posts:write' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="button">投稿</button>
</form>
{% endblock %}
書くことはそんなに多くないですよね。HTMLなんて本当はもっと書くことあります。
ここでコードを少なくしているのは、form.py
です。
最初はなんでこんなファイル作らなきゃならないのかわからなかったのですが、たくさんフォームを作るのなら明らかに効率がいいですね。あと、データベースに保存する時も便利みたいです。
データベースに保存する
このままでは『投稿』ボタンが押された時、エラーになってしまいます。
なので、views.py
にメソッドがpostの場合の処理、すなわちデータベースに保存する処理を書きましょう。
class WriteView(View):
def get(self, request, *args, **kwargs):
return render(request, 'posts/write.html', {'form': WriteForm})
def post(self, request, *args, **kwargs):
# formに書いた内容を格納する
form = WriteForm(request.POST)
# 保存する前に一旦取り出す
post = form.save(commit=False)
# 保存
post.save()
# indexのviewに移動
return redirect(to='posts:index')
write = WriteView.as_view()
これでデータベースに保存できるようになりました。
次に保存した投稿を投稿一覧で表示していきます。
投稿一覧画面
流れ
- views.pyを作成
- htmlを作成
class IndexView(View):
def get(self, request, *args, **kwargs):
# Postsテーブルのデータを全て取得
queryset = Posts.objects.all().order_by('-created_at')
# 値付きでpost.htmlに飛ぶ
return render(request, 'posts/post.html', {'posts': queryset})
index = IndexView.as_view()
ちなみに'-created_at'
と、『-』をcreated_atの前につけることで降順にデータを取得します。
結構大事。
{% extends "base.html" %}
{% block page_title %}post{% endblock %}
{% block title %}Posts{% endblock %}
{% block content %}
{% for post in posts %} ←投稿の格納された配列postsをpostとして使う
<div class="post">
<p class="text">{{ post.text }}</p>
{{ post.created_at }}
<hr>
</div>
{% endfor %}
{% endblock %}
やっと完成です〜(^○^)
非常にシンプルなコードですが、一応一通り実践してみました。
まだまだ機能拡張の余地があるのでぜひ広げてみてください。