이번 포스팅은 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 |
6 저장/수정시 유저 저장 (0) | 2016.07.27 |
5. create (0) | 2016.07.27 |
4 update delete (0) | 2016.07.25 |