カテゴリーで絞り込む

Photoモデルは、categoryというフィールドを持っており、写真を投稿するときにカテゴリーを選べるようになっています。

このレッスンでは、カテゴリー単位で写真を絞り込み、その結果をページで表示できるようにしていきます。

まずは、URLの設定です。http://127.0.0.1:8000/photos/動物/というURLで、「動物」カテゴリーの写真一覧を表示させたいので、urls.pyを以下のように追加します。

~/PhotoService/app/urls.py

urlpatterns = [
    path('', views.index, name='index'),
    path('users/<int:pk>/', views.users_detail, name='users_detail'),
    path('photos/<int:pk>/', views.photos_detail, name='photos_detail'),
    path('photos/new/', views.photos_new, name='photos_new'),
    path('photos/<int:pk>/delete/', views.photos_delete, name='photos_delete'),
    path('photos/<str:category>/', views.photos_category, name='photos_category'), # 追加
    path('signup/', views.signup, name='signup'),
    path('login/', auth_views.LoginView.as_view(template_name='app/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

views.pyは以下のようになります。URL内の<str:category>に対応する文字列で、filterをかけます。

~/PhotoService/app/views.py

from .models import Photo, Category   # 追加

def photos_category(request, category):
    # titleがURLの文字列と一致するCategoryインスタンスを取得
    category = Category.objects.get(title=category)
    # 取得したCategoryに属するPhoto一覧を取得
    photos = Photo.objects.filter(category=category).order_by('-created_at')
    return render(request, 'app/index.html', {'photos': photos, 'category':category})

テンプレート側は、トップページとほぼ同じ表示になるので、トップページでも使ってるindex.htmlを使うように設定しています。ただし、今のままだとトップページなのか、絞り込み後のページなのかがわかりづらいため、以下のように「カテゴリー:動物の検索結果」という文字が表示されるようにします。

~/PhotoService/app/templates/app/index.html

{% extends 'app/base.html' %}

{% block content %}

{% if category %}
    <h2>カテゴリー:{{ category.title }} の検索結果</h2>
{% endif %}

{% include 'app/photos_list.html' %}

{% endblock %}

{% if category %}とif文を追加することで、views.pyからcategoryが渡されたとき(つまりdef photos_categoryが実行されたとき)のみに、「検索結果」の文字が表示されます。トップページを表示するときは、index関数が実行されるのでcategoryは渡されず、この文字は表示されません。

・トップページ

・カテゴリーで絞り込んだページ

最後に、photos_list.htmlを更新して、カテゴリーボタンを押すと、絞り込み結果のページに遷移するようにしておきましょう。

~/PhotoService/app/templates/app/photos_list.html

<div class="photo-container">
{% for photo in photos %}
    <div class="photo">
        <a href="{% url 'app:photos_detail' photo.id %}">
            <img src="{{ photo.image.url }}" class="photo-img">
        </a>
        <div class="photo-info">
            <a href="{% url 'app:photos_category' category=photo.category %}" class="category">{{ photo.category }}</a>
            <a href="{% url 'app:users_detail' photo.user.id %}">@{{ photo.user }}</a>
        </div>
    </div>
{% endfor %}
</div>

これでチュートリアルは終わりです。お疲れ様でした!

< PREV
SHARE ! Tweet