-
django 'reserve a room' by FBVProject 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