ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • django 'reserve a room' by FBV
    Project using python/Cloning Airbnb 2021. 3. 13. 11:16

    url 설정

    config/urls.py

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

    rooms/urls.py

    from django.urls import path
    from reservations import views
    
    app_name = "reservations"
    
    urlpatterns = [
        path(
            "<int:room_pk>/create/<int:year>-<int:month>-<int:day>/",
            views.createReservation,
            name="create",
        ),
    ]
    

    FBV(Function Based View)

    rooms/views.py

    # reservations/views.py
    
    
    import datetime
    from django.shortcuts import redirect, reverse
    from django.contrib.auth.decorators import login_required
    from django.contrib import messages
    
    from reservations import models as reservation_models
    from rooms import models as room_models
    
    
    class CreateError(Exception):
        pass
    
    
    @login_required
    def createReservation(request, room_pk, year, month, day):
        try:
            room = room_models.Room.objects.get(pk=room_pk)
            date_obj = datetime.datetime(year, month, day)
            reservation_models.BookedDay.objects.get(day=date_obj, reservation__room=room)
            raise CreateError()
        except (room_models.Room.DoesNotExist, CreateError):
            messages.error(request, "Can't reserve that room")
            return redirect(reverse("core:home"))
        except reservation_models.BookedDay.DoesNotExist:
            reservation_models.Reservation.objects.create(
                status=reservation_models.Reservation.STATUS_PENDING,
                guest=request.user,
                room=room,
                check_in=date_obj,
                check_out=date_obj + datetime.timedelta(days=1),
            )
    
            messages.success(request, f"Reserve {room} successfully")
            return redirect(reverse("rooms:room-detail", kwargs={"pk": room_pk}))
    

    utils/cal.py

    # utils/cal.py
    
    
    import calendar
    from django.utils import timezone
    
    
    class Day:
        def __init__(self, year, month, day, past):
            self.year = year
            self.month = month
            self.day = day
            self.past = past
    
        def __str__(self):
            return str(self.day)
    
    
    class Calendar(calendar.Calendar):
        def __init__(self, year, month):
            super().__init__(firstweekday=6)
            self.year = year
            self.month = month
            self.day_names = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
            self.months = (
                "January",
                "February",
                "March",
                "April",
                "May",
                "June",
                "July",
                "August",
                "September",
                "October",
                "November",
                "December",
            )
    
        def get_month(self):
            return self.months[self.month - 1]
    
        def get_days(self):
            weeks = self.monthdays2calendar(self.year, self.month)
            days = []
            for week in weeks:
                for day, _ in week:
                    now = timezone.now()
                    this_month = now.month
                    today = now.day
                    past = False
    
                    if this_month == self.month:
                        if day <= today:
                            past = True
    
                    new_day = Day(year=self.year, month=self.month, day=day, past=past)
                    days.append(new_day)
            return days
    

    rooms/models.py

    # rooms/models.py
    
    class Room(core_models.TimeStampedModel):
        def get_calendar(self):
            now = timezone.now()
            year = now.year
            month = now.month
            next_month = month + 1
    
            if next_month == 13:
                next_month = 1
                next_year = year + 1
            else:
                next_year = year
    
            this_month_cal = Calendar(year, month)
            next_month_cal = Calendar(next_year, next_month)
            return [this_month_cal, next_month_cal]

    templates

    mixins/calendar.html

    {% load is_booked %}
    
    {% for cal in room.get_calendar %}
        <div class="{{w|default:'w-full'}} mb-10 rounded-lg shadow-lg p-5">
            <h3 class="font-bold text-lg flex justify-center mb-4">{{cal.get_month}} / {{cal.year}}</h3>
            <div class="cal-grid gap-x-1 mb-4">
            {% for day in cal.day_names %}
                <span class="font-medium">{{day}}</span>
            {% endfor %}
            </div>
            <div class="cal-grid gap-1">
            {% for day in cal.get_days %}
                {% is_booked room day as is_booked_bool%}
                {% if day.day == 0 %}
                    <span></span>
                {% else %}
                    {% if day.past %}
                        <span class="py-1 px-2 w-8 text-center text-base rounded bg-gray-200 text-white cursor-pointer line-through">{{day.day}}</span>   
                    {% elif is_booked_bool %}
                        {% if day.day in days %}
                            <span class="py-1 px-2 w-8 text-center text-base rounded bg-green-500 text-white cursor-pointer">{{day.day}}</span>
                        {% else %}
                            <span class="py-1 px-2 w-8 text-center text-base rounded bg-gray-200 text-white cursor-pointer line-through">{{day.day}}</span>   
                        {% endif %}
                    {% elif page == "reservation_page" %}
                        <span class="py-1 px-2 w-8 text-center text-base rounded bg-gray-400 text-white cursor-pointer hover:bg-red-400">{{day.day}}</span>
                    {% else %}
                        <a href="{% url 'reservations:create' room.pk day.year day.month day.day %}" class="py-1 px-2 w-8 text-center text-base rounded bg-gray-400 text-white cursor-pointer hover:bg-red-400">{{day.day}}</a>
                    {% endif %}
                {% endif %}
            {% endfor %}
            </div>
        </div>
    {% endfor %}

    reservations/templatetags/is_booked.py

    from datetime import datetime
    from django import template
    from reservations import models as reservation_models
    
    register = template.Library()
    
    
    @register.simple_tag
    def is_booked(room, day):
        if day.day == 0:
            return
        try:
            date_obj = datetime(year=day.year, month=day.month, day=day.day)
            reservation_models.BookedDay.objects.get(reservation__room=room, day=date_obj)
            return True
        except reservation_models.BookedDay.DoesNotExist:
            return False
    

    참고 자료

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

    소스 코드

    Calaendar : github.com/zpskek/airbnb-clone-v3/commit/aba16150b4b8cb445e2a345b55eaf05c929b0e0b

    create-reservation : github.com/zpskek/airbnb-clone-v3/commit/c6e00500747d94d7407773dedd30ac2b36195ecc

    'Project using python > Cloning Airbnb' 카테고리의 다른 글

    django reservation-list by CBV with ListView  (0) 2021.03.17
    django reservation-list by FBV  (0) 2021.03.15
    django delete-photo by FBV  (0) 2021.03.12
    django edit-photo by CBV  (0) 2021.03.12
    django edit photo by FBV  (0) 2021.03.12

    댓글

Designed by Tistory.