ABOUT ME

-

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

    참고 자료

    소스 코드

    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

    댓글

Designed by Tistory.