-
django create room by CBVProject using python/Cloning Airbnb 2021. 3. 8. 17:18
url 설정
config/urls.py
urlpatterns = [ path("rooms/", include("rooms.urls", namespace="room")) ]
rooms/urls.py
from django.urls import path from . import views app_name = "rooms" urlpatterns = [path("create/", views.CreateRoomView.as_view(), name="create-room")]
CBV(Class Based View)
rooms/forms.py
# rooms/forms.py from django import forms from . import models class CreateRoomForm(forms.ModelForm): """ Create Room Form Definition """ class Meta: model = models.Room fields = ( "name", "country", "city", "address", "price", "guests", "bedrooms", "beds", "bathrooms", "description", "room_type", "amenities", "facilities", "house_rules", "instant_book", ) def save(self, *args, **kwargs): room = super().save(commit=False) return room
rooms/views.py
CreateView가 존재하지만 FormView를 사용하고 따로 forms.py를 생성했다. 그 이유는 form.save를 사용하기 위해서다. form.save를 사용하는 이유는 host(ForeignKey field)를 저장하기 위해서다.
# rooms/views.py from django.views.generic import FormView from users import mixins from . import forms from photos import models as photo_models class CreateRoomView(mixins.LoginOnlyView, SuccessMessageMixin, FormView): """ Create Room View Definition """ form_class = forms.CreateRoomForm template_name = "pages/rooms/create_room.html" def form_valid(self, form): room = form.save() room.host = self.request.user room.save() form.save_m2m() caption = self.request.POST.get("caption") photo = self.request.FILES.get("photo") photo_models.Photo.objects.create(file=photo, caption=caption, room_id=room.pk) return redirect(reverse("rooms:room-detail", kwargs={"pk": room.pk}))
templates
pages/rooms/create_room.html
template은 form을 넘겨 받고 그 안에 fields를 사용한다. amenities, facilities, house_rules 같은 경우 ManyToManyField인데, amenities의 amenity의 value와 이름을 따로 가져오고 싶다면 amenity.value나 amenity.label을 하면 안 되고 amenity.data.value와 amenity.data.label로 data를 가운데에 추가해줘야 한다.
{% extends 'base.html' %} {% block page_title %} Create {{user.first_name}}'s Room {% endblock page_title %} {% block search-bar %} <div></div> {% endblock search-bar %} {% block content %} <div class="background"> <div class="wrap"> <h1 class="text-3xl font-bold pb-6 pt-3 text-center">Create Room</h1> <form method="post" class="form" enctype="multipart/form-data"> {% csrf_token %} <div class="form_input rounded-tr-lg rounded-tl-lg"> <input type="text" name="name" placeholder="Name" required> </div> <div class="select"> <label for="country">Country</label> <select name="country" id="country" required> {% for acountry in form.country %} {{acountry}} {% endfor %} </select> </div> <div class="form_input"> <input type="text" name="city" class="w-full" placeholder="City" required> </div> <div class="form_input"> <input type="text" name="address" class="w-full" placeholder="Address" required> </div> <div class="number_input"> <input type="number" name="price" class="w-full" placeholder="Price" min=0 required> </div> <div class="number_input"> <input type="number" name="guests"class="w-full" placeholder="Guests" min=0 required> </div> <div class="number_input"> <input type="number" name="bedrooms" class="w-full" placeholder="Bedrooms" min=0 required> </div> <div class="number_input"> <input type="number" name="beds" class="w-full" placeholder="Beds" min=0 required> </div> <div class="number_input"> <input type="number" name="bathrooms" min=0 class="w-full" placeholder="Bathrooms" required> </div> <div class="select"> <label for="room_type" class="text-lg font-bold">Room Type</label> {{form.room_type}} </div> <div class="form_input"> <textarea name="description" class="h-40" placeholder="Description"></textarea> </div> <div class="checkbox"> <h3>Amenity</h3> <ul> {% for amenity in form.amenities %} <li> <label for=amenity_{{amenity.data.value}}>{{amenity.data.label}}</label> <input type="checkbox" name="amenities" value="{{amenity.data.value}}" id="amenity_{{amenity.data.value}}" > </li> {% endfor %} </ul> </div> <div class="checkbox"> <h3>Facility</h3> <ul> {% for facility in form.facilities %} <li> <label for=facility_{{facility.data.value}}>{{facility.data.label}}</label> <input type="checkbox" name="facilities" value="{{facility.data.value}}" id="facility_{{facility.data.value}}" > </li> {% endfor %} </ul> </div> <div class="checkbox"> <h3>House Rules</h3> <ul> {% for house_rule in form.house_rules %} <li> <label for=house_rule_{{house_rule.data.value}}>{{house_rule.data.label}}</label> <input type="checkbox" name="house_rules" value="{{house_rule.data.value}}" id="house_rule_{{house_rule.data.value}}" > </li> {% endfor %} </ul> </div> <div class="border p-3 border-gray-400 flex justify-between"> <input type="text" name="caption" class="p-1 w-full" placeholder="Caption"> <input type="file" name="photo" class="p-1 w-full"> </div> <div class="checkbox rounded-bl-lg rounded-br-lg"> <label for="instant_book" class="text-lg font-bold mr-2">Instant Book</label> <input type="checkbox", name="instant_book" id="instant_book"> </div> <button class="form_button">Create</button> </form> </div> </div> {% endblock content %}
참고 자료
- 노마드 코더의 Airbnb 클론 강의
- template에서 form.data 사용
- form의 field 값
소스 코드
github.com/zpskek/airbnb-clone-v3/commit/0589b922b06e9cb4ca4d258e1dff4b381e623832
'Project using python > Cloning Airbnb' 카테고리의 다른 글
django edit room by CBV (0) 2021.03.09 django edit room by FBV (0) 2021.03.09 django create room by FBV (0) 2021.03.08 django Http404() (0) 2021.03.08 django translator (0) 2021.03.07