-
django edit room by CBVProject using python/Cloning Airbnb 2021. 3. 9. 08:24
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("<int:pk>/edit/", views.EditRoomView.as_view(), name="edit-room")]
CBV(Class Based View)
rooms/views.py
CBV는 django에서 정의한 여러가지 View들을 이용한다. 그 중 UpdateView를 이용해서 Edit Room page를 작성한다. UpdateView는 FormView와는 다르게 forms.py를 작성하지 않고도 View 안에서 fields를 정의할 수 있다. 아니 정의해야만 rendering이 가능하다.
get_form method를 이용해서 form의 속성을 제어할 수 있다.
# rooms/views.py from django.views.generic import UpdateView from users import mixins from . import models as room_models class EditRoomView(mixins.LoggedInOnlyView, UpdateView): model = room_models.Room template_name = "pages/rooms/edit_room.html" fields = ( "name", "country", "city", "address", "price", "guests", "bedrooms", "beds", "bathrooms", "description", "room_type", "amenities", "facilities", "house_rules", "instant_book", ) def get_form(self, form_class=None): form = super().get_form(form_class=form_class) form.fields["name"].widget.attrs = {"class": "w-full", "placeholder": "Name"} form.fields["city"].widget.attrs = {"class": "w-full", "placeholder": "City"} form.fields["address"].widget.attrs = { "class": "w-full", "placeholder": "Address", } form.fields["price"].widget.attrs = {"class": "w-full", "placeholder": "Price"} form.fields["guests"].widget.attrs = { "class": "w-full", "placeholder": "Guests", } form.fields["bedrooms"].widget.attrs = { "class": "w-full", "placeholder": "Bedrooms", } form.fields["beds"].widget.attrs = {"class": "w-full", "placeholder": "Beds"} form.fields["bathrooms"].widget.attrs = { "class": "w-full", "placeholder": "Bathrooms", } form.fields["description"].widget.attrs = { "class": "h-40", "placeholder": "Description", } return form def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) room = context["room"] s_amenities = room.amenities.all() s_facilities = room.facilities.all() s_house_rules = room.house_rules.all() context["s_amenities"] = s_amenities context["s_facilities"] = s_facilities context["s_house_rules"] = s_house_rules return context
templates
pages/rooms/edit_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 %} Edit {{room.name}} {% 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">Edit Room</h1> <form method="post" class="form"> {% csrf_token %} <div class="form_input rounded-tr-lg rounded-tl-lg"> {{form.name}} </div> <div class="select"> <label for="country">Country</label> {{form.country}} </div> <div class="form_input"> {{form.city}} </div> <div class="form_input"> {{form.address}} </div> <div class="number_input"> {{form.price}} </div> <div class="number_input"> {{form.guests}} </div> <div class="number_input"> {{form.bedrooms}} </div> <div class="number_input"> {{form.beds}} </div> <div class="number_input"> {{form.bathrooms}} </div> <div class="select"> <label for="room_type" class="text-lg font-bold">Room Type</label> {{form.room_type}} </div> <div class="form_input"> {{form.description}} </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}}" {% if amenity.data.selected %} checked {% endif %} > </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}}" {% if facility.data.selected %} checked {% endif %} > </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}}" {% if house_rule.data.selected %} checked {% endif %} > </li> {% endfor %} </ul> </div> <div class="checkbox rounded-bl-lg rounded-br-lg mb-4"> <label for="id_instant_book" class="text-lg font-bold mr-2">Instant Book</label> {{form.instant_book}} </div> <button class="form_button">Edit</button> </form> <button class="button"> <a href="#">Photo Settings</a> </button> <button class="button bg-red-600"> <a href="#">Delete Room</a> </button> <button class="button bg-gray-700"> <a href="{{room.get_absolute_url}}">Back</a> </button> </div> </div> {% endblock content %}
참고 자료
- 노마드 코더의 Airbnb 클론 강의
- template에서 form.data 사용
- form의 field 값
소스 코드
github.com/zpskek/airbnb-clone-v3/commit/91e4f93a43b782e47dc06c689fd8054fea737848
'Project using python > Cloning Airbnb' 카테고리의 다른 글
django search page by FBV (0) 2021.03.09 django delete room by FBV (0) 2021.03.09 django edit room by FBV (0) 2021.03.09 django create room by CBV (0) 2021.03.08 django create room by FBV (0) 2021.03.08