ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • django search page by FBV
    Project using python/Cloning Airbnb 2021. 3. 9. 12:43

    config/urls.py

    urlpatterns = [
        path("core/", include("core.urls", namespace="core"))
    ]

    core/urls.py

    from django.urls import path
    from rooms import views as room_views
    
    app_name = "core"
    
    urlpatterns = [
        path("search/", room_views.searchView, name="search")
    ]
    

    FBV(Function Based View)

    rooms/views.py

    # rooms/views.py
    
    from django.shortcuts import render
    from django_countries import countries
    from . import models as room_models
    
    def searchView(request):
        city = request.GET.get("city", "Anywhere")
        country = request.GET.get("country")
        price = int(request.GET.get("price", 0))
        guests = int(request.GET.get("guests", 0))
        bedrooms = int(request.GET.get("bedrooms", 0))
        beds = int(request.GET.get("beds", 0))
        bathrooms = int(request.GET.get("bathrooms", 0))
        room_type = int(request.GET.get("room_type", 0))
        s_amenities = request.GET.getlist("amenities")
        s_facilities = request.GET.getlist("facilities")
        s_house_rules = request.GET.getlist("house_rules")
        instant_book = bool(request.GET.get("instant_book"))
    
        room_types = room_models.RoomType.objects.all()
        amenities = room_models.Amenity.objects.all()
        facilities = room_models.Facility.objects.all()
        house_rules = room_models.HouseRule.objects.all()
    
        filter_args = {}
    
        form = {
            "city": city,
            "countries": countries,
            "price": price,
            "guests": guests,
            "bedrooms": bedrooms,
            "beds": beds,
            "bathrooms": bathrooms,
            "room_types": room_types,
            "amenities": amenities,
            "facilities": facilities,
            "house_rules": house_rules,
            "instant_book": instant_book,
        }
    
        choices = {
            "s_country": country,
            "s_room_type": room_type,
            "s_amenities": s_amenities,
            "s_facilities": s_facilities,
            "s_house_rules": s_house_rules,
        }
    
        if city != "Anywhere":
            filter_args["city__startswith"] = city
    
        filter_args["country"] = country
    
        if price != 0:
            filter_args["price__lte"] = price
        if guests != 0:
            filter_args["guests__gte"] = guests
        if bedrooms != 0:
            filter_args["bedrooms__gte"] = bedrooms
        if beds != 0:
            filter_args["beds__gte"] = beds
        if bathrooms != 0:
            filter_args["bathrooms__gte"] = bathrooms
    
        if room_type != 0:
            filter_args["room_type__pk"] = room_type
    
        if len(s_amenities) > 0:
            for s_amenity in s_amenities:
                filter_args["amenities__pk"] = int(s_amenity)
    
        if len(s_facilities) > 0:
            for s_facility in s_facilities:
                filter_args["facilities__pk"] = int(s_facility)
    
        if len(s_house_rules) > 0:
            for s_house_rule in s_house_rules:
                filter_args["house_rules__pk"] = int(s_house_rule)
    
        if instant_book:
            filter_args["instant_book"] = instant_book
    
        qs = room_models.Room.objects.filter(**filter_args).order_by("created")
        paginoatr = Paginator(qs, 12, orphans=6)
        page = int(request.GET.get("page", 1))
        page_sector = (page - 1) // 5
        page_sector = page_sector * 5
        rooms = paginoatr.get_page(page)
    
        return render(
            request,
            "pages/root/search.html",
            context={"rooms": rooms, "page_sector": page_sector, **form, **choices},
        )

    templates

    pages/root/base.html

          {% block search-bar %}
            <div class="w-full flex justify-center items-center">
              <form action="{% url 'core:search' %}" class="w-3/4">
                <input 
                type="text"
                placeholder="{% trans 'Searching By City' %}"
                name="city" 
                class="shadow border-none outline-none px-8 py-3 rounded-3xl w-full border-gray-500 border"
                >
              </form>
            </div>
          {% endblock search-bar %}

    pages/rooms/edit_room.html

      설명할 개념은 두 가지다.

    • field lookups : 말 그대로 db에서 field 값을 찾는 기호다. field 뒤에 (__)double under-bar를 붙이고 field lookup를 붙인다. (lte, gte, exact 등등이 있다. docs 참조)
    • slugify : template filter로 integer를 string으로 변환해 준다.
    {% extends 'base.html' %}
    
    {% block page_title %}
      Search
    {% endblock page_title %}
    
    
    {% block search-bar %}
    <div></div>
    {% endblock search-bar %}
      
    
    {% block content %}
      <div class="background mb-20">
        <div class="wrap">
          <form method="get" action="{% url 'core:search' %}" class="form">
            {% csrf_token %}
            <div class="select rounded-tr-lg rounded-tl-lg">
              <label for="country">Country</label>
              <select name="country" class="w-2/3" id="country">
                <option>Any Kind</option>
                {% for country in countries %}
                  <option value="{{country.code}}" {% if s_country == country.code %} selected {% endif %}>{{country.name}}</option>
                {% endfor %}
              </select>
            </div>
            <div class="number_input">
            <label for="city">City:</label>
              <input type="text" class="w-2/3" name="city" placeholder="City" value="{{city}}">
            </div>
            
            <div class="number_input">
            <label for="price">Price</label>
              <input type="number" class="w-2/3" name="price" placeholder="Price" min=0 value={{price}}>
            </div>
    
            <div class="number_input">
            <label for="guests">Guests</label>
              <input type="number" class="w-2/3" name="guests" min=0 placeholder="Guests" value={{guests}}>
            </div>
    
            <div class="number_input">
            <label for="bedrooms">bedrooms</label>
              <input type="number" class="w-2/3" name="bedrooms" min=0 placeholder="Bedrooms" value={{bedrooms}}>
            </div>
    
            <div class="number_input">
            <label for="beds">beds</label>
              <input type="number" class="w-2/3" name="beds" min=0 placeholder="Beds" value={{beds}}>
            </div>
    
            <div class="number_input">
            <label for="bathrooms">bathrooms</label>
              <input type="number" class="w-2/3" name="bathrooms" min=0 placeholder="Bathrooms" value={{bathrooms}}>
            </div>
            
            <div class="select">
            <label for="room_type" class="text-lg font-bold">Room Type</label>
              <select name="room_type" class="w-2/3" id="room_type">
                <option value="0" {% if s_room_type == room_type.pk %} selected {% endif %}>Any Kind</option>
                {% for room_type in room_types %}
                  <option value="{{room_type.pk}}" {% if s_room_type == room_type.pk|slugify %} selected {% endif %}> {{room_type}}</option>
                {% endfor %}
              </select>
            </div>
    
            <div class="checkbox">
              <h3>Amenity</h3>
              <ul>
              {% for amenity in amenities %}
                <li>
                  <label for=amenity_{{amenity.pk}}>{{amenity.name}}</label>
                  <input
                    type="checkbox"
                    name="amenities"
                    value="{{amenity.pk}}"
                    id="amenity_{{amenity.pk}}"
                    {% if amenity.pk|slugify in s_amenities %}
                      checked
                    {% endif %}
                    >
                </li>
              {% endfor %}
              </ul>
            </div>
    
            <div class="checkbox">
              <h3>Facility</h3>
    
              <ul>
              {% for facility in facilities %}
                <li>
                  <label for=facility_{{facility.pk}}>{{facility.name}}</label>
                  <input
                    type="checkbox"
                    name="facilities"
                    value="{{facility.pk}}"
                    id="facility_{{facility.pk}}"
                    {% if facility.pk|slugify in s_facilities %}
                      checked
                    {% endif %}
                    >
                </li>
              {% endfor %}
              </ul>
            </div>
    
            <div class="checkbox">
              <h3>House Rules</h3>
              <ul>
              {% for house_rule in house_rules %}
                <li>
                  <label for=house_rule_{{house_rule.pk}}>{{house_rule.name}}</label>
                  <input
                    type="checkbox"
                    name="house_rules"
                    value="{{house_rule.pk}}"
                    id="house_rule_{{house_rule.pk}}"
                    {% if house_rule.pk|slugify in s_house_rules %}
                      checked
                    {% endif %}
                    >
                </li>
              {% endfor %}
              </ul>
            </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" {% if instant_book %}checked{% endif %}>
            </div>
            <button class="form_button">Search</button>
          </form>
        </div>
      </div>
      <div class="flex flex-col items-center justify-items-center mt-10">
        <div class="w-10/12">
            {% include 'mixins/room_card.html' with rooms=rooms %}
            <div class="flex justify-center mt-20 itmes-center">
            {% include 'mixins/page_number.html' with page=rooms %}
          </div>
        </div>
      </div>
    {% endblock content %}

    참고 자료

    소스 코드

    github.com/zpskek/airbnb-clone-v3/commit/d5958b6a6927497190725121f6ad4eb0f0d1998b

    'Project using python > Cloning Airbnb' 카테고리의 다른 글

    django photo list by CBV  (0) 2021.03.11
    django photo list by FBV  (0) 2021.03.11
    django delete room by FBV  (0) 2021.03.09
    django edit room by CBV  (0) 2021.03.09
    django edit room by FBV  (0) 2021.03.09

    댓글

Designed by Tistory.