データの受け取り(クラスベースビューから)
データの受け取り
前回は関数ベースのviewからデータを受け取りましたが、今回はクラスベースのviewからデータを受け取る方法に取り組んで行きます。
下準備
sample_app/models.py
from django.db import models
class News(models.Model):
title = models.CharField(max_length=50, verbose_name='タイトル')
content = models.TextField(verbose_name='本文')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='作成日')
is_public = models.BooleanField(default=False)
sample_app/admin.py
from django.contrib import admin
from .models import News
admin.site.register(News)
sample_app/urls.py
from django.urls import path
from . import views
app_name = 'sample_app'
urlpatterns = [
path('', views.news_list, name='news_list'),
path('news/<int:id>', views.news_detail, name='news_detail'),
]
sample_app/views.py
from django.views.generic import ListView, DetailView
from .models import News
class NewsListView(ListView):
template_name = 'sample_app/news-list.html'
model = News
paginate_by = 10
news_list = NewsListView.as_view()
class NewsDetailView(DetailView):
template_name = 'sample_app/news-detail.html'
model = News
news_detail = NewsDetailView.as_view()
ターミナル
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
touch templates/sample_app/news-list.html
touch templates/sample_app/news-detail.html
ここまで出来たらadminサイトにログインしてデータを入れましょう。
ターミナル
python manage.py runserver
http://127.0.0.1:8000/admin
にアクセスしてスーパーユーザー作成時の情報を入力します。
ログイン後管理画面が開かれているはずです。
sample_appのNewssの追加を押しましょう。
すると作成フォームが表示されるはずです。
適当に記事を3つほど作りましょう。
news-list.html, news-detail.htmlでデータを受け取る
ここからが本題です。
先程views.py
に書いたNewsListView
とNewsDetailView
からデータを受け取って表示させましょう。
それぞれnews-list.html
, news-detail.html`で受け取り、表示させます。
templates/sample_app/news-list.html
{% extends 'base.html' %}
{% load static %}
{% block main %}
<ul class="list-group">
<li class="list-group-item active">News</li>
{% for object in object_list %}
<li class="list-group-item"><a href="{% url 'sample_app:news_detail' object.pk %}">{{ object.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
templates/sample_app/news-detail.html
{% extends 'base.html' %}
{% load static %}
{% block main %}
<h2 class="text-primary">{{ object.title }}</h2>
<p>{{ object.content }}</p>
{% endblock %}
python manage.py runserver
してhttp://127.0.0.1:8000/
にアクセスすると、管理サイトで入力した情報が表示されてるかと思います。
NewsListView
からはobject_list
, NewsDetailView
からはobject
で情報を取得出来ます。
しかしこれではコードの可読性がいまいちですね。
view.py
でそれぞれのクラスベースビューにcontext_object_name
を指定しましょう。
views.py
from django.views.generic import ListView, DetailView
from .models import News
class NewsListView(ListView):
template_name = 'sample_app/news-list.html'
model = News
paginate_by = 10
context_object_name = 'newses' # ここ
news_list = NewsListView.as_view()
class NewsDetailView(DetailView):
template_name = 'sample_app/news-detail.html'
model = News
context_object_name = 'news' # ここ
news_detail = NewsDetailView.as_view()
こうすることでobject_list
ではなくnewses
で、object
ではなくnews
で受け取ることが出来ます。
templates/sample_app/news-list.html
{% extends 'base.html' %}
{% load static %}
{% block main %}
<ul class="list-group">
<li class="list-group-item active">News</li>
{% for news in newses %}
<li class="list-group-item"><a href="{% url 'sample_app:news_detail' news.pk %}">{{ news.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
templates/sample_app/news-detail.html
{% extends 'base.html' %}
{% load static %}
{% block main %}
<h2 class="text-primary">{{ news.title }}</h2>
<p>{{ news.content }}</p>
{% endblock %}
可読性がさっきよりもよくなりましたね。
Just Python フリープラン
ジャスパイなら教材は全て無料!