[Django] choices field 검색하기

itisny·2023년 11월 7일
0
post-custom-banner
# models.py

#...
    CUISINE_CHOICES = [
        (KOREAN, "한식"),
        (WESTERN, "양식"),
        (JAPANESE, "일식"),
        (CHINESE, "중식"),
        (ASIAN, "아시안음식"),
        (SNACKS, "분식"),
        (CAFE, "카페"),
        (FAST_FOOD, "패스트푸드"),
        (OTHER, "기타"),
    ]
    
#...  
  
    cuisine = models.CharField(
    max_length=2, choices=CUISINE_CHOICES, help_text="어떤 종류의 음식인가요?"
)

#... 

CharField에 choices에 지정할 요소를 따로 빼주었다. CUISINE_CHOICES의 리스트에서 각 튜플에 있는 첫 번째 요소는 DB에 저장할 실제 값이고, 두 번째 요소는 display용 이름이다.

>>> python manage.py shell
>>> from restaurants.models import Restaurant
  File "<console>", line 1, in <module>
>>> Restaurant.objects.all()
<QuerySet [<Restaurant: Test>, <Restaurant: Test2>, <Restaurant: Test3>, <Restaurant: Testt>]>
>>> Restaurant.objects.filter(cuisine__icontains="korean")
<QuerySet []>
>>> Restaurant.objects.filter(cuisine__icontains="한식")
<QuerySet [<Restaurant: Test>, <Restaurant: Testt>]>

필터링이 되는 것은 DB에 저장한 실제값이 아니라, display용 이름이다.

# view.py

class RestaurantList(ListView):
    model = Restaurant
    ordering = "-pk"

    def get_queryset(self):
        qs = super().get_queryset()
        cuisine = self.request.GET.get("cuisine", "")
        if cuisine:
            qs = qs.filter(cuisine=cuisine)
        return qs

cuisine = self.request.GET.get("cuisine", "")

<form action="" method="GET">
    {% csrf_token %}
    <label for="cuisine">음식 종류</label>
    <select name="cuisine" id="cuisine">
      <option value="" {% if not request.GET.cuisine %}selected{% endif %}>전체</option>
      <option value="한식" {% if request.GET.cuisine == "한식" %}selected{% endif %}>한식</option>
      <option value="양식" {% if request.GET.cuisine == "양식" %}selected{% endif %}>양식</option>
      <option value="일식" {% if request.GET.cuisine == "일식" %}selected{% endif %}>일식</option>
      <option value="중식" {% if request.GET.cuisine == "중식" %}selected{% endif %}>중식</option>
      <option value="아시안음식" {% if request.GET.cuisine == "아시안음식" %}selected{% endif %}>아시안 음식</option>
      <option value="분식" {% if request.GET.cuisine == "분식" %}selected{% endif %}>분식</option>
      <option value="카페" {% if request.GET.cuisine == "카페" %}selected{% endif %}>카페</option>
      <option value="패스트푸드" {% if request.GET.cuisine == "패스트푸드" %}selected{% endif %}>패스트푸드</option>
      <option value="기타" {% if request.GET.cuisine == "기타" %}selected{% endif %}>기타</option>
    </select>
  </form>

전체 옵션에만 selected를 넣었었다. 하지만 get 요청을 하면 selected한 전체 옵션으로 초기화되었다. 물론 필터링이 되긴했지만 ux적으로 좋아보이지 않았다. 그래서 {% if request.GET.cuisine == "한식" %} selected {% endif %}을 각 조건마다 추가해주었다. (템플릿 태그 안, 띄어쓰기 주의하기!!)
이제 get요청을 해도 선택한 요소가 그대로 남아있는 것을 확인할 수 있다.

post-custom-banner

0개의 댓글