文章目录
- 1. View
-
- 1.2 简介
- 1.1 requests对象
- 1.2 代码
- 2. APIView
-
- 3. GenericAPIView
-
- 4. GenericAPIView之过滤分页排序
-
- 4.1 过滤
- 4.2 排序
- 4.3 分页
- 4.4 代码
1. View
1.2 简介
- Django默认的视图基类,引用方式:
from django.views import View
- 视图views.py有两种写法,基于类或基于函数
1.1 requests对象
- request.META:获取一个标准的python字典,它包含了所有的HTTP请求信息
- request.scheme:请求的方式,http或https
- request.path:请求路径
- request.session:获取的是一个类似于字典的对象,可以进行读取写入操作
- request.method:请求方式 POST/GET
- request.body:获取请求数据,常见用法json.loads(request.body.decode(‘utf-8’), encoding=‘utf-8’)
1.2 代码
import json
from django.http import JsonResponse, Http404
from django.views import View
from projects.models import Projects
from projects.serializers import ProjectsModelSerializers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class ProjectList(View):
""""
类视图
"""
def get(self, request):
qs = Projects.objects.all()
serializer = ProjectsModelSerializers(instance=qs, many=True)
return JsonResponse(serializer.data, safe=False, status=200)
def post(self, request):
"""
httpie模拟请求:http POST :8000/projects/ name='项目009' leader="zz" developer='李四' tester='张三' \
app_name='测试应用' desc='demo desc'
"""
data = json.loads(request.body.decode('utf-8'), encoding='utf-8')
serializer = ProjectsModelSerializers(data=data)
try:
serializer.is_valid(raise_exception=True)
except Exception as e:
return JsonResponse(serializer.errors)
serializer.save()
return JsonResponse(serializer.data, safe=False, status=201)
2. APIView
2.1 与View对比
- APIView继承自Django的View,使用时视图需要继承APiView
- 传入到视图的是Request对象而不是Django的HttpRequest对象
- 视图方法可以返回Response对象,会把响应数据处理(render)为符合前段要求的格式,取决于accept这个参数
- 任何APIException异常都会被捕获到,并且处理成合适的响应信息
- 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制
2.2 view代码
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from projects.models import Projects
from projects.serializer import ProjectModelSerializer
class ProjectList(APIView):
""""
类视图
"""
def get(self, request):
projects = Projects.objects.all()
serializer = ProjectModelSerializer(instance=projects, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request):
"""
httpie json格式请求模拟:http POST :8000/projects/ name='项目009' leader="zz" developer='李四' tester='王五' app_name='测试应用' desc='demo desc'
httpie form-data格式请求模拟:http -f POST :8000/projects/ name='项目009' leader="zz" developer='李四' tester='王五' app_name='测试应用' app_version='1.0' desc='demo desc'
"""
serializer = ProjectModelSerializer(data=request.data)
try:
serializer.is_valid(raise_exception=True)
except Exception as e:
return Response(serializer.errors)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
3. GenericAPIView
3.1 简介
- 继承关系: rest_framework.generics.GenericAPIView—>rest_framework.views.APIView—>django.views.generic.base.View—>obiect—>typing.hashable
- 必须指定的属性: queryset、serializer_class
视图类继承自GenericAPIView后进行排序
3.2 对比
项目 |
View |
APIView |
GenericAPIView |
继承自 |
Object |
View |
APIView |
params获取 |
request.GET |
request.query_params |
request.query_params |
json获取 |
request.body |
request.data |
request.data |
data获取 |
request.POST |
request.data |
request.data |
file获取 |
request.FILES |
request.data |
request.data |
return |
JsonResponse |
Response |
request.data |
4. GenericAPIView之过滤分页排序
4.1 过滤
pip install django-filter
INSTALLED_APPS = [
...
'rest_framework',
'django_filters',
]
from projects.models import Projects
from projects.serializers import ProjectsModelSerializers
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status
class ProjectList(GenericAPIView):
queryset = Projects.objects.all()
serializer_class = ProjectsModelSerializers
filter_backends = [DjangoFilterBackend]
filterset_fields = ['id', 'name', 'leader']
def get(self, request):
"""
http://127.0.0.1:8000/projects/?id=6&name=项目5&leader=风清扬
"""
qs = self.get_queryset()
qs = self.filter_queryset(qs)
serializer = self.get_serializer(instance=qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
4.2 排序
from django_filters.rest_framework import DjangoFilterBackend
from projects.models import Projects
from projects.serializers import ProjectsModelSerializers
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status, filters
class ProjectList(GenericAPIView):
queryset = Projects.objects.all()
serializer_class = ProjectsModelSerializers
filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
filterset_fields = ['id', 'name', 'leader']
ordering_fields = ['id', 'name', 'leader']
def get(self, request):
"""
倒序:http://127.0.0.1:8000/projects/?ordering=-id
"""
qs = self.get_queryset()
qs = self.filter_queryset(qs)
serializer = self.get_serializer(instance=qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
4.3 分页
- 必须指定分页引擎,可以在类视图中,也可以在全局settings.py中指定
- 必须指定
PAGE_SIZE
from django_filters.rest_framework import DjangoFilterBackend
from projects.models import Projects
from projects.serializers import ProjectsModelSerializers
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status, filters
from rest_framework.pagination import PageNumberPagination
class PageNumberPaginationManual(PageNumberPagination):
page_query_param = 'page_num'
page_size_query_param = 'page_size'
page_size = 2
max_page_size = 50
page_query_description = '第几页'
page_size_query_description = '每页几条'
class ProjectList(GenericAPIView):
queryset = Projects.objects.all()
serializer_class = ProjectsModelSerializers
pagination_class = PageNumberPaginationManual
def get(self, request):
"""
分页:http://127.0.0.1:8000/projects/?page_num=3&page_size=3
"""
qs = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(qs)
if page is not None:
serializer = self.get_serializer(instance=page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(instance=qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
4.4 代码
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'django_filters',
'interfaces.apps.InterfaceConfig',
'projects.apps.ProjectConfig'
]
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.OrderingFilter',
'django_filters.rest_framework.backends.DjangoFilterBackend']
'DEFAULT_PAGINATION_CLASS': 'utils.pagination.PageNumberPaginationManual',
'PAGE_SIZE': 3
}
from rest_framework.pagination import PageNumberPagination
class PageNumberPaginationManual(PageNumberPagination):
page_query_param = 'page_num'
page_size_query_param = 'page_size'
page_size = 10
max_page_size = 50
from projects.models import Projects
from projects.serializers import ProjectsModelSerializers
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status, filters
class ProjectList(GenericAPIView):
queryset = Projects.objects.all()
serializer_class = ProjectsModelSerializers
filterset_fields = ['id', 'name', 'leader']
ordering_fields = ['id', 'name', 'leader']
def get(self, request):
"""
过滤:http://127.0.0.1:8000/projects/?id=6&name=项目5&leader=风清扬
倒序:http://127.0.0.1:8000/projects/?ordering=-id
分页:http://127.0.0.1:8000/projects/?ordering=name&page_num=3&page_size=3
"""
qs = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(qs)
if page is not None:
serializer = self.get_serializer(instance=page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(instance=qs, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request):
"""
httpie模拟请求:http POST :8000/projects/ name='项目009' leader="zz" developer='李四' tester='张三' \
app_name='测试应用' desc='demo desc'
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
class ProjectDetail(GenericAPIView):
"""
模型类继承自GenericAPIView后,无需定义get_object方法
"""
queryset = Projects.objects.all()
serializer_class = ProjectsModelSerializers
lookup_field = 'id'
def get(self, request, id):
"""
httpie模拟请求:http :8000/projects/12
"""
qs = self.get_object()
serializer = ProjectsModelSerializers(instance=qs)
return Response(serializer.data, status=status.HTTP_200_OK)
def put(self, request, id):
"""
httpie模拟请求:http PUT :8000/projects/12 name='项目0091' leader="张三" developer='李四' \
tester='王五' app_name='测试应用' desc='demo desc'
"""
qs = self.get_object()
serializer = self.get_serializer(instance=qs, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
def delete(self, request, id):
"""
httpie模拟请求:http DELETE :8000/projects/12
"""
qs = self.get_object()
qs.delete()
return Response(None, status=status.HTTP_204_NO_CONTENT)