티스토리 뷰

study/Django

Django - Query string 2

xoxowo 2022. 9. 7. 11:40

이전 포스팅에서 작성했던 방법은 선택 항목이 늘어날수록 코드를 재수정해야 한다는 점 때문에 이번 3차 프로젝트에는 코드 리팩터링을 하다 Q객체를 이용하여 query string을 좀 더 확장성 있게 구현해 보기로 했다.

 

처음 equipment list url로 들어왔을 때 등록된 모든 장비 항목이 보여야 된다.

그 후 선택(옵션) 값을 Query string으로 값을 받아서 필터링으로 값을 빼와서 결괏값을 다시 전달해주면 된다.

 

마찬가지로 list를 보는 페이지는 equipment/list로 끝나게끔 url 주소를 정의했다.

# equipment/urls.py 파일
from django.urls import path

from equipment.views import EquipmonetListView, EquipmentDetailView, AnalysisView

urlpatterns = [
   path('/list', EquipmonetListView.as_view()),
   path('/detail/<int:equipment_id>', EquipmentDetailView.as_view()),
   path('/analysis', AnalysisView.as_view()),
]

 

 

equipment/views.py를 보면 type = request.GET.getlist('type', ['값 1', '값 2', '값3'])에서 뒤의 리스트 인자가 defult값으로 미리 리스트 안에있는 '값1', '값2', '값 3'이 처음 페이지에 모두 보이도록 설정했었다.

 

이 방법은 선택 항목이 늘어날수록 코드를 재수정해야 한다는 점 때문에 Q객체를 사용하여 코드를 수정해봤다.

 

Q 객체 사용

* Q객체는 장고에서 제공하는 기능이기 때문에 import를 해야 사용할 수 있다. (from django.db.models import Q)

1. 조건을 담을 변수(q)를 선언해준다.

2. request.GET.getlist의 'tyep'과 'area'에 값이 들어오면 아래 if문이 실행되면서 q에 각 조건들이 담아진다.

여기서 주의할 점은 q &= Q(조건=값),  q |= Q(조건=값)처럼 &= |=을 어떻게 사용하냐에 따라 값이 달라진다.

(Q가 약간 도라에몽 주머니랑 비슷하다고 느꼈다. 계속 담을 수 있는 🧐)

3. 조건이 담긴 q를 filter에 담는다.

4. 만약 'tyep'과 'area'에 값이 들어오지 않는다면 &= 을 사용했기 때문에 Q() 은 Product.objects.all()과 같은 결과를 얻는다.

# equipment/views.py 파일
class EquipmonetListView(View):
    def get(self, request):
        try:				       	    # 변경 후 -> 변경 전
            type      = request.GET.getlist('type') # -> ('type', ['whell_loader', 'backhoe'])
            area      = request.GET.getlist('area') # -> ('type', ['구역A', '구역B'])
            sort_type = request.GET.get('sort_by', 'all') # 정렬 옵션 
            
            sort_options = {
                'all'      : 'serial_number',
                'equipment': 'type__name',
            }
	   # q에 Q객체 선언 (?)	
            q =  Q()            
            if type:
                q &= Q(type__name__in=type)   
            if area:
                q &= Q(area__id__in=area)
	   # Q()주머니에 담은 검색 조건들을 filter에 넣어 검색
            equipments = Equipment.objects.filter(q)
           # 예외 처리
            if not equipments:
              return JsonResponse({'message':'Dose_Not_Exist'}, status=404)
           # 이하 생략 ...

 

+ Q객체는 아직 많이 사용해보지 않아서 위 코드 내용이 틀렸을 수 있지만.. 프로젝트 이후에도 리펙토링을 할 예정이기 때문에 (+예외처리) 나중에 기회가 되면 Q에 대해 공부한 내용을 남겨야겠다 🥹 

'study > Django' 카테고리의 다른 글

환경 변수 설정 (django-environ)  (0) 2023.04.13
Unit Test 작성  (0) 2023.03.02
CSRF - Cross Site Request Forgeries  (0) 2022.09.05
Django - Query String  (0) 2022.08.17
Django - 동일한 테이블을 참조하는 ForeignKey  (0) 2022.07.31
댓글