이번 포스팅은 search에 대한 전반적인 로직을 포스팅할 예정입니다. 


1. 먼저 로그인한 유저의 데이터만 볼수 있도록 list 부분을 수정해 보도록 하겠습니다. 


현재 저장된 데이터는 아래 화면처럼 4개 입니다. 3개는 1번인 admin  / 1개는 3번인 testuser 입니다. 




2. post/api/views.py 에서 PostListAPIView()에 get_queryset()을 오버라이딩 합니다. 


get_queryset()은 GeneriView에서 어떤 데이터를 가져올 것인지에 대한 query를 총괄하는 함수 입니다. 

기존에 사용하던 queryset이 바로 get_queryset 라고 보시면 됩니다. 

파라미터중 self.request 를 통해서 파라미터를 받아서 처리하게끔 하면 됩니다. 

자세한 사항은 아래의 링크를 참조하세요.

http://www.django-rest-framework.org/api-guide/generic-views/#get_querysetself 


이번에는 로그인한 유저의 데이터만을 가져오므로 filter()를 사용해서 user를 매칭시켜 줍니다. 


class PostListAPIView(ListAPIView):
serializer_class = PostSerializer

def get_queryset(self, *args, **kwargs):
queryset_list = Post.objects.filter(user=self.request.user)

return queryset_list


3. 다시 /api/posts/를 보시면 해당 유저의 데이터 리스트만을 리턴해 줍니다. 



4. 이번에는 url파라미터로 q값을 받아서 q와 매칭되는 데이터만을 가져오는것을 해보겠습니다. 

q로 매칭될 데이터들은 title / content / 유저 이름 으로 해보겠습니다. 

filter()의 Q()의 like인 __icontains를 써서 아래와 같이 쿼리를 짰습니다. 그리고 마지막에 .distinct()함수를 통해서 중복을 제거해 줍니다.


from django.db.models import Q
class PostListAPIView(ListAPIView):
serializer_class = PostSerializer

def get_queryset(self, *args, **kwargs):
queryset_list = Post.objects.all()
query = self.request.GET.get("q")
if query:
queryset_list = queryset_list.filter(
Q(title__icontains=query) |
Q(content__icontains=query) |
Q(user__first_name__icontains=query) |
Q(user__last_name__icontains=query)
).distinct()
return queryset_list


5. 이번의 주소는 /api/posts/?q=포스트   입니다. 

타이틀이 포스트이거나 본문 내용이 포스트 이거나 유저 이름이 포스트가 되는 데이터들은 모두 가져오는 거죠. 쉽죠?!



6. 아직 유저 이름은 넣어주지 않았으므로 /admin/에서 user 변경으로 들어갑니다. 


7. 저의 경우 admin유저의 이름을 admin admin 으로 수정하였습니다. 



8. 다시 /api/posts/?q=admin 으로 하면 아래와 같이 admin 유저의 데이터 리스트를 보여줍니다. 




9. 이번엔 쿼리가 아닌 rest_framework.filters 에서 제공하는 search를 구현해 보겠습니다. 

먼저 아래의 searchFilter 과 OrderingFilter를 import합니다. 

그리고 PostListAPIView()에 filter_backends[]와 search_fields[]를 선언해 줍니다. 


filter_backends는 사용할 필터의 정의를 search_fields는 필터링할 컬럼을 정의합니다. 

해당 컬럼은 당연히 시리얼라이져에 정의된 필드를 기준으로 합니다. 

자세한 사항은 아래의 링크를 참조하시면 됩니다. 

http://www.django-rest-framework.org/api-guide/generic-views/#filter_querysetself-queryset

from rest_framework.filters import SearchFilter, OrderingFilter



class PostListAPIView(ListAPIView):
serializer_class = PostListSerializer
filter_backends = [SearchFilter, OrderingFilter]
search_fields = ['title', 'content']

def get_queryset(self, *args, **kwargs):
queryset_list = Post.objects.all()
query = self.request.GET.get("q")
if query:
queryset_list = queryset_list.filter(
Q(title__icontains=query) |
Q(content__icontains=query) |
Q(user__first_name__icontains=query) |
Q(user__last_name__icontains=query)
).distinct()
return queryset_list



10. 단지 두줄만 추가 했을뿐인데 작동하니는지 볼까요?

/api/posts/?search=포스트 로 접속해보면 포스트가 저장된 데이터들만 뽑아 오는것을 볼수 있습니다!!


11. 여기에 아까 로직을 만들었던 q도 같이 써보면

/api/posts/?search=저장&q=admin 으로 한다면

admin유저의 포스트중 저장이라고 된 포스트만을 가져오게 됩니다. 


12. 이번엔 ordering 차례 입니다. 

/api/posts/?ordering=pk 로 하시면 pk 내림 차순으로 리턴된것을 볼수 있습니다. 



13. 오름 차순은 -만 붙여주시면 됩니다. 

/api/posts/?ordering=-pk






저작자 표시
신고

'web > Django_rest_framework' 카테고리의 다른 글

9. href  (0) 2016.07.30
8 pagination  (0) 2016.07.29
7 search  (0) 2016.07.28
6 저장/수정시 유저 저장  (0) 2016.07.27
5. create  (0) 2016.07.27
4 update delete  (0) 2016.07.25

WRITTEN BY
No.190
세계정복의 시작점

받은 트랙백이 없고 , 댓글이 없습니다.
secret