5
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Djangoで掲示板アプリを1から作るの。(その3)

Posted at

その2
https://qiita.com/TuruMaru/items/8b55d1e134f29b8a8dcd

#ちょっとだけCSS

$mkdir static
$touch base.css

プロジェクト直下にstaticディレクトリを作り、その中にcssファイルを作成します。
staticは静的という意味で、静的なファイルを入れておくみたいです。

mysite/setting.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

設定ファイルにこれを追加する。

templates/base.html
{% 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をヒョヒョイっと書いちゃいます。

templates/base.html
{% 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>
static/base.css
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.pyurls.pyに投稿を書く画面(write)を追加します。

posts/views.py
class WriteView(View):
    def get(self, request, *args, **kwargs):
        return render(request, 'posts/write.html')


write = WriteView.as_view()
posts/urls.py
app_name = 'posts'
urlpatterns = [
    path('', views.index, name='index'),
    path('write/', views.write, name='write'), これを追加
]
スクリーンショット 2019-11-05 11.24.22.png

そしたらこんな感じに整います。

投稿一覧画面(post)と投稿を書く画面(write)のどっちを先にやろうかな〜って考えたんですけど、投稿を書く画面(write)からやっちゃいます。

投稿作成画面

入力フォームを作成し、入力内容をデータベースに保存します。

流れ

  1. form.pyの作成
  2. views.pyの作成
  3. htmlの作成

まずはフォームだけ

$cd posts
$touch form.py
posts/form.py
from django import forms
from .models import Posts


class WriteForm(forms.ModelForm):
    class Meta:
        #モデルを指定
        model = Posts
        #フォームとして表示したいカラムを指定
        fields = ('text',)
posts/views.py
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()
templates/posts/write.html
{% 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 %}

できる画面がこれです。
スクリーンショット 2019-11-05 16.24.03.png

書くことはそんなに多くないですよね。HTMLなんて本当はもっと書くことあります。
ここでコードを少なくしているのは、form.pyです。
最初はなんでこんなファイル作らなきゃならないのかわからなかったのですが、たくさんフォームを作るのなら明らかに効率がいいですね。あと、データベースに保存する時も便利みたいです。

データベースに保存する

このままでは『投稿』ボタンが押された時、エラーになってしまいます。
なので、views.pyにメソッドがpostの場合の処理、すなわちデータベースに保存する処理を書きましょう。

posts/views.py
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()

これでデータベースに保存できるようになりました。
次に保存した投稿を投稿一覧で表示していきます。

投稿一覧画面

流れ

  1. views.pyを作成
  2. htmlを作成
views.py
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の前につけることで降順にデータを取得します。
結構大事。

templates/posts/post.html
{% 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 %}

これで一覧画面を見てみると
スクリーンショット 2019-11-06 2.40.40.png

やっと完成です〜(^○^)
非常にシンプルなコードですが、一応一通り実践してみました。
まだまだ機能拡張の余地があるのでぜひ広げてみてください。

5
9
2

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
5
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?