【Django(日報アプリ開発)】ユーザー別の日報リストページを作成する方法を解説!

Django

(最終更新月:2021年10月)

前回の記事では、django-filterを導入し、Bootstrapクラス動的なchoicesの作成方法について解説しました

当記事では、

  • ユーザー別のリストビューを作成する方法

について解説していきます

最終的にはこんな形になりました

localhost:8000/profile-view/admin-1/

localhost:8000/profile-view/ユーザー名-プライマリーキー/

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

はじめに

のちのち編集などの必要が出てきたときのために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を返すこと

が特に重要な部分です

この方法は色々なアイディアを形にする上で、応用の効く方法かと思いますので、是非頭に入れておきましょう

さて、アプリ公開に向けての機能の追加はこれまでとします

次回の記事でもう少し見た目を整えたら、いよいよアプリ公開へ進んでいきましょう

タイトルとURLをコピーしました