django中drf的视图类、分页、排序、过滤

温顾练习的保存

先读概念,再看使用代码

版本信息: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={})

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值