(最終更新月:2021年10月)
前回の記事では、django-filterを導入し、Bootstrapクラス、動的なchoicesの作成方法について解説しました
当記事では、
- ユーザー別のリストビューを作成する方法
について解説していきます
最終的にはこんな形になりました

でアクセスをし、対象のユーザー名、プライマリーキーを持つプロフィールユーザーの日報を表示する、というページになります

おススメ記事!興味ある方はこちらもどうぞ!
はじめに
のちのち編集などの必要が出てきたときのためにfilterのコードを別ファイルへ保存します
nippo > nippo-top-filter.html
<form method="GET">
<div class="my-3">
{{ filter.form.date.label }} {{ filter.form.date}}
</div>
<div class="my-3">
{{ filter.form.public }}
</div>
<button type="submit" class="btn btn-primary form-control">ソート</button>
</form>
nippo-list.htmlではincludeタグを使いフィルターへアクセスします
{% include 'nippo/nippo-top-filter.html' %}
前準備は完了です
ユーザー別リストビューを作っていきましょう
NippoListViewByProfileクラス
views.py内で新たなクラスを作成します
nippo > views.py
from django.shortcuts import get_object_or_404
class NippoListViewByProfile(NippoListView):
template_name = "nippo/nippo-list-by-profile.html"
def get_profile(self):
try:
username, pk = self.kwargs["obj_slug"].split("-")
except:
username = None
pk = None
profile_obj = get_object_or_404(Profile, pk=pk)
return profile_obj
def get_queryset(self):
qs = super().get_queryset()
qs = qs.filter(user__profile=self.get_profile())
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx["username"] = self.get_profile().username
return ctx
NippoListViewを継承することで活用できるメソッドはそのまま引き継ぐようにしましょう
get_profileメソッドで、URLで受け取ったスラッグの「pk」を取り出し、Profileオブジェクトを返します
get_querysetメソッドでは、filterを使い対象のプロファイルユーザーが作成した日報のみ表示するよう記述しています※user__profileの「__」はアンダーバー2つになります
get_context_dataメソッドではテンプレート上でusernameを表示する必要があるため、取得したプロファイルユーザーのユーザー名をusernameに格納しテンプレートへ渡しています
関連書籍
urls.pyでアクセスURLを設定
urlpatterns = [
...,
path("profile-view/<slug:obj_slug>/", NippoListViewByProfile.as_view(), name="nippo-by-profile"),
...,
]
views.pyではスラッグを「obj_slug」という変数で受け取っているため、当urls.py内でも
/<slug:obj_slug>/
としています
nippo-list-by-profile.html
テンプレートを作成しましょう
nippo > templates > nippo > nippo-list-by-profile.html
nippo-list.htmlをコピペし、少しだけ編集しました
{% extends "base.html" %}
{% block content %}
<div class="container">
{% include 'nippo/nippo-top-filter.html' %}
{% if filter.qs %}
<h2 class="text-center">{{ username }}の日報</h2>
{% for obj in filter.qs %}
<div class="card my-3 mx-auto" style="max-width:700px;">
<div class="card-header">
{{ obj.date|date:"Y年n年j日" }}
{% if not obj.public %}
<span class="badge bg-secondary">下書き</span>
{% endif %}
</div>
<div class="card-body">
<h5 class="card-title">
{% if obj.user == request.user %}
<a href={% url 'nippo-update' obj.slug %}>
{{ obj.title}}
<span style="font-size:10px;">
(編集)
</span>
{% else %}
<a href={% url 'nippo-detail' obj.slug %}>
{{ obj.title}}
{% endif %}
</a>
</h5>
<p class="card-text">
{{ obj.content }}
</p>
</div>
</div>
{% endfor %}
{% endif %}
</div>
{% endblock %}
h2タグでユーザー名をタイトルとして表示したことや表示されている日報が下書きなのかそうでないかがわかるように変更を加えています
動的なリンクを作成するメソッド
プロフィール別のページへは、トップページである日報リストビューからユーザー名をクリックしアクセスするように設定していきます
日報オブジェクトからプロフィールユーザーページのリンクを作成するメソッドを作りましょう
nippo > models.py
NippoModelクラス内で新たなメソッドを定義します
def get_profile_view_url(self):
return reverse_lazy("nippo-by-profile", kwargs={"obj_slug": f"{self.user.profile.username}-{self.user.profile.pk}"})
これにより、
日報オブジェクト.get_profile_view_url
とすることで、ユーザー別のページへのリンクを作成することが可能になりました
nippo-list.html
作成したリンクを挿入します
nippo > templates > nippo > nippo-list.html
{% if obj.user == request.user %}
<span class="badge bg-primary">
<a class="text-light" href={{obj.get_profile_view_url}}>あなた</a>
</span>
{% else %}
<span class="badge bg-secondary">
<a class="text-light" href={{obj.get_profile_view_url}}>
{{ obj.user.profile.username }}
</a>
</span>
{% endif %}
ユーザー名を表示する箇所にリンクを追加しました
最低限の部分のみ抜粋していますので記述場所にご注意ください
おわりに
これにてユーザー別日報リストページの作成が終わりました
まとめると、
- URLよりユーザーを特定できる情報を受け取る
- 受け取った情報をviews.pyで処理し、正しいQuerySetを返すこと
が特に重要な部分です
この方法は色々なアイディアを形にする上で、応用の効く方法かと思いますので、是非頭に入れておきましょう
さて、アプリ公開に向けての機能の追加はこれまでとします
次回の記事でもう少し見た目を整えたら、いよいよアプリ公開へ進んでいきましょう
日報アプリを一から開発し、ウェブに公開するまではこちらにまとめています
また、公開したウェブアプリはこちら(https://nippo.itc-app.site)でご覧いただけます(公開後もアップデート中)
その他、各分野別に
を記載したページも用意しています
ご自身の目的に合わせて、お好きな箇所からご覧ください
