温顾练习的保存
先读概念,再看使用代码
版本信息:python3,django2.2
参考示例:jwt_view.py
drf: object、View、APIView、GenericAPIView、ViewSet
#### GenericAPIView支持定义的属性
##### 1. 列表与详情视图通用
queryset: 列表视图的查询集
<br>
serializer_class: 视图使用的序列化器
##### 2. 列表试图使用
pagination_class: 分页控制类
<br>
filter_backends: 过滤控制后端
##### 3. 详情视图使用
lookup_field: 查询单一数据库对象时使用的字段,默认'pk'
<br>
lookup_url_kwars: 查询单一数据时url中的参数关键字名称,默认与lookup_field相同
#### GenericAPIView提供的方法
##### 1. 列表与详情视图通用
get_queryset(self): 返回视图使用的查询集
<br>
get_serializer_class(self): 返回序列化器类,默认返回serializer_class
<br>
get_serializer(self, *args, **kwargs): 返回序列化器对象
<br>
##### 2. 详情视图
get_object(self): 返回详情视图所需的模型类数据对象,默认使用lookup_field来过滤queryset,不存在,返回404
- - -
* * *
#### 五个扩展类
1. viewsets -> ModelViewSet:(1)CreateModelMixin (2)RetrieveModelMixin (3)UpdateModelMixin
(4)DestroyModelMixin(5)ListModelMixin
2. generics -> (1)ListAPIView (2)RetrieveAPIView (3)DestroyAPIView等等9个
3. ViewSet视图集类,不再实现get、post方法,而是实现action动作,如list()、create(),自定义动作时,用action装饰器
#### ViewSet常用视图集父类
1. ViewSet,继承APIView,作用也类似(需自己实现)
2. GenericViewSet,作用和GenericAPIView类似(需自己实现)
3. ModelViewSet,继承GenericAPIView,同时包括了增删改查
4. ReadOnlyViewSet,继承GenericAPIView,同时包括了详情、列表
#### 认证、权限、限流
1. 在settings.py配置可全局控制,在视图中单个控制
#### 过滤Filtering
1. pip install django-filter
2. 在配置文件中增加过滤后端的设置,注册应用,并且配置REST_FRAMEWORK
~~~
REST_FRAMEWORK = {
“DEFAULT_FILTER_BACKENDS”: ('django_filter.rest_framework.DjangoFilterBackend',)
}
~~~
3. 在视图中添加filter_fields属性
#### 排序
1. drf提供了OrderFilter过滤器,按照指定字段排序
2. 使用方法:在类视图中,设置filter_backends,使用rest_framework。filters.OrderFilter过滤器,
请求参数中检查是否包含ordering参数.
~~~
filter_backends = [OrderingFilter]
ordering_fields = ("id",)
~~~
#### 分页
1. settings.py文件中配置全局分页
~~~
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination'
'PAGE_SIZE': 10 # 每页10条
}
~~~
2. 也可通过自定义Pagination类,为仕途添加不同分页行为,在视图中通过pagination_class属性指明
~~~
# 视图中
pagination_class = None # 关闭全局分页设置
from rest_framework.pagination import PageNumberPagination
class PaginatorManager(PageNumberPagination):
pass
# 页数
page = 1
# 每页条数
page_size = 10
# 查询字段,默认page
page_query_param = 'page'
# 每页条数参数
page_size_query_param = None
page_size_query_description = ('Number of results to return per page.')
# 最多只能展示每一页条数
max_page_size = 1000
~~~
""" drf的四种开发方式,以及 分页、限流、认证、排序、权限等等 以下部分字段不一定存在,只是都练习到写上"""
# 一、函数式编程
@api_view(["GET", "POST"])
def test_list(request):
"""
获取数据
"""
if request.method == "GET":
query_set = Student.objects.all()
s = StudetSerializer(query_set, many=True)
return JsonResponse({"datas": s.data, "status": status.HTTP_200_OK})
elif request.method == "POST":
s = StudetSerializer(data=request.data, partial=True) # partial 非必传部分更新,定义5个,传3个,只更新3个
if s.is_valid():
s.save(teacher="12321") # 前端不传的字段,查到后可通过这种去传入
return JsonResponse({"datas": s.data, "status": status.HTTP_200_OK})
return JsonResponse({"datas": s.errors, "status": status.HTTP_400_BAD_REQUEST})
elif request.method == "PUT":
student = Student.objects.get(id=1)
s = StudetSerializer(instance=student, data=request.data)
if s.is_valid:
s.save()
# 二、类编程
class TestList(APIView):
def get(self, request):
# 无新知识,跟上面一致
pass
def post(self, request):
# 无新知识,跟上面一致
pass
# 三、通用视图类
class StudentsViewsetss(generics.ListCreateAPIView):
# generics.CreateAPIView 新建 post
# generics.DestroyAPIView 删除 delete
# generics.UpdateAPIView 更新 put
# generics.RetrieveUpdateAPIView 获取、更新、删除操作的VIEW
# queryset、serializer_class等的名称是固定的,哪些不满足,看看源码可以重写方法
queryset = Student.objects.all()
serializer_class = StudetSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) # raise_exception是否抛出异常,一般都是true
print(serializer.is_valid(raise_exception=True))
# 以下为逻辑段
if "flag" in request.data:
self.perform_create(serializer)
return Response("保存成功", status=status.HTTP_201_CREATED)
else:
return Response("保存失败", status=status.HTTP_400_BAD_REQUEST)
# 四、drf的视图集viewset
class TestViewSet(viewsets.ModelViewSet):
queryset = Student.objects.filter(id=1)
serializer_class = StudetSerializer
def perform_create(self, serializer):
serializer.save(teacher="123")
"""
一、 此种写法比较麻烦
get:请求方式
list: ModelViewSet->ListModelMixin->list方法
重要!!!!路由写法, url(r'viewsets/$', TestViewSet.as_view({
"get": "list",
"post": "create",
"put": "update",
"delete": "destroy"
}), name="viewsets-list"),
二、 routers (用这种)
router.register(r'students', TestViewSet, basename="test")
"""
# method_decorator的作用是为函数视图装饰器补充第一个self参数,以适配类视图方法, method_decorator 是将函数装饰器转换成方法装饰器。
@method_decorator(csrf_exempt, name="dispatch") # post, 一种取消csrf
class LogView(APIView):
@csrf_exempt # 二种取消csrf
def get(self, request):
# django内置密码加密
pwd = request.GET.get("pwd")
# 加密算法,默认pbkdf2_sha256,hasher参数指定算法
make = make_password(pwd)
log.info("输出加密密码:{}".format(make))
if check_password(pwd, make):
log.info("校验成功")
return JsonResponse(data={})
class ModelsView(APIView):
def get(self, request):
# student = Student.objects.create(name="123", sex="女", number="456123")
# techer = Teacher.objects.create(techer_name="www")
sql = Student.objects.filter(name="123").query # 返回原始sql
'''
update_or_create: 更新或新建
defaults: 新建参数
**kwargs: 匹配字段
'''
# Teacher.objects.update_or_create(defaults={},techer_name="www")
return JsonResponse(data={})