How to implement filter API in Django rest framework
我正在Django REST中尝试实现过滤器API。有点像-
1 | localhost:8000/api/v1/users/[email protected]/ |
因此,它应该使用传递的过滤器搜索用户并返回结果。但目前它正在返回所有用户。
URLS.Py
1 2 3 | url(r'^api/v1/users/$', UserViews.UserList.as_view(), name='userlist_view'), url(r'^api/v1/users/(?P.+)/$', UserViews.UserList.as_view(), name='userList_view'), url(r'^api/v1/users/(?P<pk>[0-9]+)/$', UserViews.UserDetail.as_view(), name='userdetail_view'), |
用户视图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class UserList(generics.ListAPIView): """ List all users, or create a new user. """ lookup_url_kwarg ="email" def get(self, request, format=None): if request.user.is_authenticated(): users = User.objects.all() serializer = UserSerializer(users, many=True) return Response(serializer.data) return Response("User is not authenticated.", status=status.HTTP_400_BAD_REQUEST) def post(self, request, format=None): valid_paylaod, msg = UserListRepository.validations_create_user(request.data) if not valid_paylaod: return Response(msg, status=status.HTTP_400_BAD_REQUEST) result = UserListRepository.create_user_repo(request) if not result.success: return Response(str(result.msg), status=result.status ) return Response(UserSerializer(result.data).data, status=result.status) def get_queryset(self): # It restricts the userlist by retunning users having emails passed in uery param user = self.request.user if user.is_authenticated(): if 'email' in self.request.query_params: email = self.request.query_params.get('email', None) users = User.objects.get(email= email) if not users: return Response("User Not found", status=status.HTTP_404_NOT_FOUND) else: return Response(UserSerializer(User.objects.all()).data, status.HTTP_200_OK, users) else: return Response(UserSerializer().data, status=result.status) else: return Response("User is not authenticated.", status=status.HTTP_400_BAD_REQUEST) |
有人能告诉我们为什么请求不能得到用户列表方法的queryset()方法和get()。删除get方法时,请求转到getu queryset(self)方法。在调试时,我发现在返回语句之前得到了有效的响应-
1 2 | (Pdb) UserSerializer(result.data).data {'parent_id': 2, 'id': 31, 'group_id': '4', 'last_name': 'user', 'email': '[email protected]', 'organization_id': 0, 'first_name': 'agency22'} |
但在API响应中,我得到以下错误:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Internal Server Error: /api/v1/users/ Traceback (most recent call last): File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/django/core/handlers/base.py", line 149, in get_response response = self.process_exception_by_middleware(e, request) File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/django/core/handlers/base.py", line 147, in get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) Fi e"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view return view_func(*args, **kwargs) File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view return self.dispatch(request, *args, **kwargs) File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/views.py", line 466, in dispatch response = self.handle_exception(exc) File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/views.py", line 463, in dispatch response = handler(request, *args, **kwargs) File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/generics.py", line 201, in get return self.list(request, *args, **kwargs) File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/mixins.py", line 43, in list if page is not None: File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/serializers.py", line 674, in data ret = super(ListSerializer, self).data File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site-packages/rest_framework/serializers.py", line 239, in data self._data = self.to_representation(self.instance) File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site- packages/rest_framework/serializers.py", line 614, in to_representation self.child.to_representation(item) for item in iterable File"/Users/richagupta/VirtualEnvs/py35/lib/python3.5/site- packages/django/template/response.py", line 173, in __iter__ raise ContentNotRenderedError('The response content must be ' django.template.response.ContentNotRenderedError: The response content must be rendered before it can be iterated over. |
我不清楚为什么。我要访问的API URL是:localhost:8000/api/v1/用户?电子邮件[email protected]
问题是您正在覆盖
1 2 3 4 5 6 7 8 9 10 | def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) |
如果重写此方法,则必须自己调用
1 2 3 4 | def get(self, request, format=None): if request.user.is_authenticated(): return super(UserList, self).get(request, format) return Response("User is not authenticated.", status=status.HTTP_400_BAD_REQUEST) |
看起来您使用的是django的
您必须从restframework.response导入响应
1 | from rest_framework.response import Response |
在django-rest框架中,有一个关于如何使用过滤器的适当规范。所以你的用户类应该是这样的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | class UserList(generics.ListAPIView): """ List all users, or create a new user. """ lookup_url_kwarg ="email" serializer_class = UserSerializer def get(self, request, format=None): if request.user.is_authenticated(): users = User.objects.all() serializer = UserSerializer(users, many=True) return Response(serializer.data) return Response("User is not authenticated.", status=status.HTTP_400_BAD_REQUEST) def post(self, request, format=None): valid_paylaod, msg = UserListRepository.validations_create_user(request.data) if not valid_paylaod: return Response(msg, status=status.HTTP_400_BAD_REQUEST) result = UserListRepository.create_user_repo(request) if not result.success: return Response(str(result.msg), status=result.status ) return Response(UserSerializer(result.data).data, status=result.status) def get_queryset(self): email = self.request.query_params.get('email', None) return User.objects.filter(email=email) |
或者您可以尝试不使用get_queryset。链接将更改,更新的链接为:
更新后的代码是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class UserList(generics.ListCreateAPIView): """ List all users, or create a new user. """ lookup_url_kwarg ="email" serializer_class = UserSerializer def get(self, request, email,format=None): if request.user.is_authenticated(): user_details = User.objects.filter(email=email) serializer = UserSerializer(user_details, many=True) return Response(serializer.data, status=status.status.HTTP_200_OK) return Response("User is not authenticated.", status=status.HTTP_400_BAD_REQUEST) def post(self, request, format=None): valid_paylaod, msg = UserListRepository.validations_create_user(request.data) if not valid_paylaod: return Response(msg, status=status.HTTP_400_BAD_REQUEST) result = UserListRepository.create_user_repo(request) if not result.success: return Response(str(result.msg), status=result.status ) return Response(UserSerializer(result.data).data, status=result.status) |
我被URLCONF弄糊涂了:
1 2 | url(r'^api/v1/users/$', UserViews.UserList.as_view(), name='userlist_view'), url(r'^api/v1/users/(?P.+)/$', UserViews.UserList.as_view(), name='userList_view'), |
- 第一个是给
localhost:8000/api/v1/users/ 的 第二个是针对
localhost:8000/api/v1/users/[email protected]/ 而不是localhost:8000/api/v1/users/[email protected]/ 的,这是一个查询参数而不是kwargs,如果您想使用查询参数,请选中它。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28class UserList(generics.ListAPIView):
"""
List all users, or create a new user.
"""
lookup_url_kwarg ="email"
serializer_class = UserSerializer
def post(self, request, format=None):
valid_paylaod, msg = UserListRepository.validations_create_user(request.data)
if not valid_paylaod:
return Response(msg, status=status.HTTP_400_BAD_REQUEST)
result = UserListRepository.create_user_repo(request)
if not result.success:
return Response(str(result.msg), status=result.status )
return Response(UserSerializer(result.data).data, status=result.status)
def get_queryset(self):
"""
It restricts the userlist by return users having emails passed in query param
"""
queryset = Users.objects.all()
email = self.request.query_params.get('email', None)
if email is not None:
queryset = queryset.filter(email=email)
return queryset