本棚アプリケーションの作成【4-9 CreateViewでブラウザ上からデータを作成しよう】

データをブラウザ上で作れるようにしよう

ここからCreateViewを作っていきます。

CreateViewはブラウザ上で入力されたデータがデータベースに反映(追加)されるという点において、少しコードの中身が変わります。

まずはurls.pyファイルの実装を進めていきます。

ListViewと同じような形で書いていきましょう。

bookproject/book/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view()),
    path('book/<int:pk>/detail/', views.DetailBookView.as_view())
]

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view()),
    path('book/<int:pk>/detail/', views.DetailBookView.as_view()),
    path('book/create/', views.CreateBookView.as_view()),
]

に編集

次にviews.pyファイルを編集します。

bookproject/book/views.py

from django.shortcuts import render
from django.views.generic import ListView, DetailView
from .models import Book

class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView
from .models import Book

class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

class CreateBookView(CreateView):
    template_name = 'book/book_create.html'
    model = Book

に編集

htmlファイルの作成

book_create.htmlファイルを作成していきます。

(venv) $ touch book/templates/book/book_create.html

そして以下のコードを書き込んでいきます。

bookproject/book/templates/book/book_create.html

{% extends 'base.html' %}

{% block title %}書籍作成{% endblock %}

{% block content %}
    <form method='POST'>
        {{form.as_p}}
        <input type='submit' value="作成する">
    </form>
{% endblock content %}

これで実装が完了しました。

CreateViewで必要な設定

サーバーを立ち上げて、ブラウザでhttp://127.0.0.1:8000/book/create/にアクセス

(venv) $ python3 manage.py runserver 

そしたらエラーがでます。これは指定したテーブルの中で、どの項目を使うか指定してください、ということを意味しています(fieldsを指定していないことによるエラー)

fieldsの追加

views.pyを編集していきます

bookproject/book/views.py

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView
from .models import Book

class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

class CreateBookView(CreateView):
    template_name = 'book/book_create.html'
    model = Book

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView
from .models import Book

class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

class CreateBookView(CreateView):
    template_name = 'book/book_create.html'
    model = Book
    fields = ('title','text','category')

に編集。

これで再度ブラウザでhttp://127.0.0.1:8000/book/create/にアクセス

入力フォームが表示されました。

入力フォームにデータを入れた上で送信ボタンをクリックしてみましょう。

するとエラーがでます。

このエラーは、CSRF(クロスサイトリクエストフォージェリ)のトークンが発行されていないことを示します。

このエラーを解決するためにはcsrf_tokenのタグを埋め込む必要があります。

さっそくcsrf_tokenのタグを埋め込んでいきましょう。

bookproject/book/templates/book/book_create.html

{% extends 'base.html' %}

{% block title %}書籍作成{% endblock %}

{% block content %}
    <form method='POST'>
        {{form.as_p}}
        <input type='submit' value="作成する">
    </form>
{% endblock content %}

{% extends 'base.html' %}

{% block title %}書籍作成{% endblock %}

{% block content %}
    <form method='POST'>{% csrf_token %}
        {{form.as_p}}
        <input type='submit' value="作成する">
    </form>
{% endblock content %}

に編集。

これで再度ブラウザでhttp://127.0.0.1:8000/book/create/にアクセスして入力フォームにデータを入力して送信ボタンをクリックしましょう。

今度は、どのページに遷移させるかが指定されていないことを示すエラーです。

エラーを解決するためにURLを指定していきます。

bookproject/book/views.py

from django.shortcuts import render
from django.views.generic import ListView, DetailView, CreateView
from .models import Book

class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

class CreateBookView(CreateView):
    template_name = 'book/book_create.html'
    model = Book
    fields = ('title','text','category')

from django.shortcuts import render
from django.urls import reverse_lazy
from django.views.generic import ListView, DetailView, CreateView
from .models import Book

class ListBookView(ListView):
    template_name = 'book/book_list.html'
    model = Book

class DetailBookView(DetailView):
    template_name = 'book/book_detail.html'
    model = Book

class CreateBookView(CreateView):
    template_name = 'book/book_create.html'
    model = Book
    fields = ('title','text','category')
    success_url = reverse_lazy('list-book')

に編集。

bookproject/book/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view()),
    path('book/<int:pk>/detail/', views.DetailBookView.as_view()),
    path('book/create/', views.CreateBookView.as_view()),
]

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book'),
    path('book/<int:pk>/detail/', views.DetailBookView.as_view()),
    path('book/create/', views.CreateBookView.as_view()),
]

に編集。

そしてもう一度編集します。

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book'),
    path('book/<int:pk>/detail/', views.DetailBookView.as_view()),
    path('book/create/', views.CreateBookView.as_view()),
]

from django.urls import path
from . import views

urlpatterns = [
    path('book/', views.ListBookView.as_view(), name='list-book'),
    path('book/<int:pk>/detail/', views.DetailBookView.as_view(),name='detail-book'),
    path('book/create/', views.CreateBookView.as_view(), name='create-book'),
]

に編集。

これでCreateViewの実装は完了です。