ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • django edit room by CBV
    Project 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 %}

    참고 자료

    소스 코드

    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

    댓글

Designed by Tistory.