초보 개발자

django Filtering 본문

Python/airbnb 클론

django Filtering

taehyeki 2022. 2. 8. 17:40

field lookups를 활용하면 원하는 조건을 상세하게 지정하여 찾을 수 있다. 

우리는 search기능을 만들어 조건에 맞는 방들을 추리기 위한 기능을 만들어 볼 것이다.

먼저 search.html을 만들고 우리가 설정한 필드의 값들을 다 담아주었다.

views에서도 값을 받아와서, filtering을하고 다시 그 값을 html에 보내주어 우리가 원하는 조건이 모두 체크되어 있도록 해주었다. 

먼저 filter를 해주기 위해서 qs에 모든 방을 담아둔다. filter()만해두면 모든 값이 다 들어오게 된다.

filter_args라는 딕셔너리를 만들고 거기에 조건을 하나하나 추가해 나가는 방식이다

 

city

city에 아무 값도 없다면 기본값이 Anywhere로 해두었다. 만약 Anywhere이 아니라면 특정 도시가 들어올 것이다.

startswith를 사용하면 도시를 전부 입력하지 않아도 앞 몇글자만 일치하면 반환해준다.

예를들어서 우리는 seo만 적어도 Room의 city가 Seoul로 되어 있다면 반환해준다. 필드명__field lookup 형식으로 사용한다.

 

country

이건 별도의 분기문을 주지 않았다. 기본값으로 'KR'이 들어오며, 다른 값이 들어오면 그 값으로 필터링해준다.

 

roomtype

Any kind의 값을 0으로 주었다. 0이라면 모든 room_type을 다 검색하는 것이기에 그게 아닌 경우라는 분기문을 달은 것이다. city도 마찬가지, 아무튼 room_type__pk라고 두었는데 이 이유는 room_type은 Room의 foreign key이다 따라서 foreign key의 필드에 접근하려면 언더바 2개 __를 붙이면 가능하다. 따라서 정확한 값을 찾아주는 room_type__pk__exact를 사용해도 되지만 굳이 사용할 필요가 없을거같기에 room_type__pk 에 room_type의 값을 넣어주었다.

 

price

price가 기본값 0이 아니라면 filter조건에 받아온 금액보다 적은 금액의 필터조건을 추가한다.

 

guests

bedrooms

beds

baths

마찬가지로 기본값 0이 아니라면 filter조건에 받아온 수보다, 더 큰 숫자의 필터조건을 추가한다.

 

superhost

instant

체크박스가 체크되면 서버에 'on'이라는 걸로 넘어오기에, 'on'은 분기문에서 True로 사용할 수 있다. 따라서 True인 경우에 필터 조건을 추가해주었다.

 

**를 사용하여 dict를 언패킹을 해주었고 이를 통해 해당 조건에 맞는 방들이 rooms로 들어오게 된다.

그리고 나서 amenities와, facilities의 조건도 확인 해주어야한다. 이 두개는 왜 filter_args에 넣지 않았냐면,

값이 여러개이기 때문이다. TV, WI-FI, Shower ... 여러 조건에 해당하는 방들만 골라주어야 하기때문에 for문을 돌면서 일일이 확인해주어야 한다. 따라서 받아온 s_amenities의 값을 토대로 필터를 해주고 다시 그 필터된 값을 rooms에 넣어주어야한다. 갱신을 해주지 않으면 결국 마지막 amenitiy의 값만 필터링 되기 때문이다.

 

모든 방마다 filter가 진행이된다. -> filter조건은 각 방의 여러 amenities(many to many)들의 pk값과 일치한다면 그 방을 남기고 아니면 없앤다. -> 이렇게 반복을해서 우리가 고른 모든 amenities들이 있는 방들이 남게된다.

 

신기한 점이 amenities의 pk는 여러개 이고, 우리가 비교하는 값은 하나int(s_amenity)인데 이게 가능한가 싶었는데 신기하게도 비교를 해주었다. 

 

다음 글에서 form으로 더 간단하게 만드는 방법을 배워보자

'Python > airbnb 클론' 카테고리의 다른 글

django S3, RDS 연동해보기 !  (0) 2022.02.10
django Filtering Form API  (0) 2022.02.09
Http404, FBV detail -> CBV detail  (0) 2022.02.07
url 'namespace : name', reverse, get_absolute_url  (0) 2022.02.07
listview  (0) 2022.02.06