Project using python/Cloning Airbnb
django 'reserve a room' by FBV
Cog Factory
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