店舗をクリックすると、スタッフリストが表示されるようにします。

モデル

スタッフモデルを追加します。

スタッフはログインユーザーと連携するようにしています。

app/models.py

from accounts.models import CustomUser


class Staff(models.Model):
    user = models.OneToOneField(CustomUser, verbose_name='スタッフ', on_delete=models.CASCADE)
    store = models.ForeignKey(Store, verbose_name='店舗', on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.store}{self.user}'

コード解説

CustomUserと連携させることによって、ログインユーザーがスタッフとなります。

OneToOneFieldを使うことによって、スタッフと店舗をユニークにすることができます。

スタッフは店舗の掛け持ちができなくなります。

user = models.OneToOneField(CustomUser, verbose_name='スタッフ', on_delete=models.CASCADE)

Admin

管理画面でデータを登録できるようにします。

app/admin.py

from django.contrib import admin
from .models import Store, Staff

admin.site.register(Store)
admin.site.register(Staff)

マイグレーション実行

モデルを追加したので、マイグレーションが必要になります。

(myvenv) ~$ python3 manage.py makemigrations
(myvenv) ~$ python3 manage.py migrate

データ追加

管理画面で staff モデルにスタッフデータを追加します。

現在は、管理ユーザーのみしかないので、ナビゲーションのスタッフから新しいアカウントを作りましょう。

何件かアカウントを作成してスタッフ登録しておくとレイアウトがしやすくなります。

URL

スタッフリストの URL を作成します。

app/urls.py

from django.urls import path
from app import views

urlpatterns = [
    path('', views.StoreView.as_view(), name='store'),
    path('store/<int:pk>/', views.StaffView.as_view(), name='staff'), # 追加
]

ビュー

スタッフリストのビューを作成します。

app/views.py

from django.shortcuts import get_object_or_404, render
from app.models import Store, Staff


class StaffView(View):
    def get(self, request, *args, **kwargs):
        store_data = get_object_or_404(Store, id=self.kwargs['pk'])
        staff_data = Staff.objects.filter(store=store_data).select_related('user')

        return render(request, 'app/staff.html', {
            'store_data': store_data,
            'staff_data': staff_data,
        })

コード解説

get_object_or_404関数を使用することで、店舗データがひとつもない場合に、404 エラーを返してくれます。

self.kwargs['pk']で URL の店舗 ID を取得することができます。

store_data = get_object_or_404(Store, id=self.kwargs['pk'])

テンプレート

staff

店舗情報とスタッフリストを表示するテンプレートを作成します。

app/templates/app/staff.html

{% extends "app/base.html" %} {% block content %}

<div class="text-center my-5">
  <div class="row">
    <div class="col-md-6 mb-4 text-center stafflist">
      <img src="/{{ store_data.image.url }}" class="img-fluid" alt="" />
    </div>

    <div class="col-md-6 mb-4">
      <div class="card">
        <div class="card-body px-2 py-1">
          <div class="p-4 text-left">
            <h3>{{ store_data.name }}店</h3>
            <hr />
            <p>住所:{{ store_data.address }}</p>
            <p>TEL:{{ store_data.tel }}</p>
            <p>{{ store_data.description|linebreaksbr }}</p>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div class="mb-5">
    <h1>スタッフ一覧</h1>
  </div>
  <div class="row">
    {% for staff in staff_data %}
    <div class="col-lg-3 col-md-6">
      <div class="card img-thumbnail storelist mb-3">
        <img
          class="card-img-top card-thum"
          src="/{{ staff.user.image.url }}"
          alt=""
        />
        <div class="card-body text-center px-2 py-3">
          <h5 class="font-weight-bold">
            {{ staff.user.first_name }} {{ staff.user.last_name }}
          </h5>
        </div>
        <a class="stretched-link" href=""></a>
      </div>
    </div>
    {% empty %}
    <p>まだスタッフがいません</p>
    {% endfor %}
  </div>
</div>

{% endblock %}

store

店舗をクリックするとスタッフリストに遷移したいので、リンクを追加します。

app/templates/app/store.html

<a class="stretched-link" href="{% url 'staff' store.pk %}"></a>

CSS

CSS でスタッフリスト画面を装飾します。

app/static/css/style.css

/* staff */

.stafflist img {
  height: 250px;
  object-fit: contain;
}

確認

店舗をクリックして、スタッフリスト画面がこのように表示されるか確認してください。

スタッフリスト