ブログの非公開記事一覧を作る

Python Django

概要

Djangoで、ブログを作るシリーズ①の1つです。非公開にした記事の一覧ページを作っていきます。

ビューの作成

まず、urls.pyに追記します。

from django.urls import path
from . import views

app_name = 'nblog1'

urlpatterns = [
    path('', views.PublicPostIndexView.as_view(), name='top'),
    path('private/', views.PrivatePostIndexView.as_view(), name='private_post_list'),  # 追加
]

そしてビューを作成します。views.pyを次のようにします。

from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Q
from django.views import generic
from .forms import PostSearchForm
from .models import Post


class PublicPostIndexView(generic.ListView):
    """公開記事の一覧を表示する。"""
    paginate_by = 10
    model = Post
    queryset = Post.objects.filter(is_public=True)

    def get_queryset(self):
        queryset = super().get_queryset()
        self.form = form = PostSearchForm(self.request.GET or None)
        if form.is_valid():
            # 選択したタグが含まれた記事
            tags = form.cleaned_data.get('tags')
            if tags:
                for tag in tags:
                    queryset = queryset.filter(tags=tag)

            # タイトルか本文にキーワードが含まれたもの
            # キーワードが半角スペースで区切られていれば、その回数だけfilterする。つまりAND。
            key_word = form.cleaned_data.get('key_word')
            if key_word:
                for word in key_word.split():
                    queryset = queryset.filter(Q(title__icontains=word) | Q(text__icontains=word))

        queryset = queryset.order_by('-updated_at').prefetch_related('tags')
        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['search_form'] = self.form
        return context


class PrivatePostIndexView(LoginRequiredMixin, PublicPostIndexView):
    """非公開の記事一覧を表示する。"""
    raise_exception = True
    queryset = Post.objects.filter(is_public=False)

今回作る非公開記事の一覧は、もともとあったPublicPostIndexViewと殆ど処理は同じです。PublicPostIndexViewはis_publicがTrueの記事で、PrivatePostIndexViewはその逆なだけです。なので、継承を使って殆どの処理を引き継ぎ、クラス属性のquerysetでそれぞれのビュー特有の絞り込みをしています。

また、LoginRequiredMixinを使うことでログインしないと非公開記事一覧は見れないようにしています。raise_exception = Trueなので、非公開記事一覧ページにアクセスしたけど、ログインしていない場合は403ページに直行します。

ちなみにデフォルトはFalseで、403ではなくログインページにリダイレクトします。ログインページの存在そのものを隠したいという場合は、今回のようにTrueにしておくと良いでしょう。

これで/privateにアクセスすると、非公開記事一覧ページが表示されるようになります。今回はやりませんでしたが、ログインしている場合はページ上部にでも、非公開記事一覧ページへのリンクを表示する、等も良いでしょう。

Relation Posts

Comment

記事にコメントする

まだコメントはありません。