Project using python/Cloning Airbnb

django reservation-list by CBV with ListView

Cog Factory 2021. 3. 17. 05:36

url 설정

config/urls.py

urlpatterns = [
    path("rooms/", include("rooms.urls", namespace="room"))
]

reservations/urls.py

from django.urls import path
from . import views

app_name = "reservations"

urlpatterns = [
	path(
        "user/<int:user_pk>/",
        views.ReservationListView.as_view(),
        name="list",
    )]

CBV(Class Based View)

reservations/views.py

  CBV는 django에서 정의한 여러가지 View들을 이용한다. 그 중 ListView를 이용해서 reservation-list page를 작성한다. ListView는 model을 꼭 정의해줘야 한다. 하지만 model은 DB 안에 있는 모든 record를 가져온다. 내가 원하는 특정 목록만 가져오고 싶을 경우 model을 정의하지 않고 get_queryset() method를 이용해서 특정 list만 반환하면 된다.

# reservations/views.py

from django.views.generic import ListView
from django.shortcuts import redirect, reverse

from reservations import models as reservation_models
from users import mixins

class ReservationListView(mixins.LoggedInOnlyView, ListView):

    """ Reservation List View Definition """

    template_name = "pages/reservations/reservation_list.html"
    context_object_name = "reservations"
    paginate_by = 12
    paginate_orphans = 6
    ordering = "created"

    def get_queryset(self):
        user_pk = self.kwargs.get("user_pk")

        if user_pk != self.request.user.pk:
            return redirect(reverse("core:home"))

        return reservation_models.Reservation.objects.filter(guest_id=user_pk)

    def get_context_data(self):
        page = int(self.request.GET.get("page", 1))
        page_sector = (page - 1) // 5
        page_sector = page_sector * 5
        context = super().get_context_data()
        context["page_sector"] = page_sector
        return context

templates

pages/reservations/reservation_list.html

{% extends 'base.html' %}

{% load remainder_op %}

{% block page_title %}
    {{request.user}}'s Reservation List
{% endblock page_title %}

{% block content %}
    <div class="flex flex-col items-center justify-items-center">
        <div class="w-10/12">
            {% include 'partials/reservation_card.html' %}
            <div class="flex justify-center mt-20 itmes-center">
                {% include 'mixins/page_number.html' with page=page_obj %}
            </div>
        </div>
    </div>
{% endblock content %}

partials/reservation_card.html

<ul class="grid grid-cols-4 grid-rows-2-300px auto-rows-300px gap-4 gap-y-6">
    {% for reservation in reservations %}
        <li class="w-full">
            <a href="#">
                <div class="rounded-lg bg-cover bg-center h-3/4 mb-2" style="background-image:url('{{reservation.room.get_first_photo}}')">
                    <div class="flex items-center {% if reservation.room.host.superhost %}justify-between{% else %}justify-end{% endif %}">
                        {% if reservation.room.host.superhost %}
                            <span class="bg-white p-2 ml-2  mt-2 rounded-lg font-semibold justify-start">Superhost</span>
                        {% endif %}
                        <i class="far fa-heart mr-2 mt-2 text-2xl text-white justify-end text-center"></i>
                    </div>
                </div>
                <div class="h-1/4">
                    <div class="mb-1">
                        <i class="fas fa-star text-red-500"></i>
                        <span class="review-points">{{reservation.room.get_review_points}}</span>
                        <span class="text-gray-400">({{reservation.room.reviews.count}})</span>
                    </div>
                    <div class="truncate">
                        {{reservation.room.country}} &bull; {{reservation.room.address}}
                    </div>
                </div>
            </a>
        </li>
    {% endfor %}
</ul>

참고 자료

  • 노마드 코더의 Airbnb 클론 강의

소스 코드

github.com/zpskek/airbnb-clone-v3/commit/08261cdc63fcb7aef57ad0bc9b5b376d987d44be