笔记: Django Rest Framework 视图

1, 先写一个APP, 名字叫dsj

1.1 urls.py文件内容如下:

from django.urls import path, re_path, include
from django.conf.urls import url
from . import views

#下面是用rest framework的路由系统是设置
from rest_framework import routers
router = routers.DefaultRouter() #实例化一个默认的类
router.register(prefix=r'xxx', viewset=views.V3View) #注册到系统中去,注意这里的参数,prefix是前缀的意思,生成的url中会有这个,viewset就是想要对哪个视图进行注册,这里是V3View
router.register(prefix=r'rt', viewset=views.V3View) #这里不会错,因为前缀不同,生成的url是不同的.注册到系统中去,注意这里的参数,prefix是前缀的意思,生成的url中会有这个,viewset就是想要对哪个视图进行注册,这里是V3View
#如何验证上面的路由设置,以及下面的设置,只要我们在url中写错,那么就会报错出来好多路由,就可以看到是不是有自动生成的路由url


urlpatterns = [
    re_path(r'^roles/$', views.RolesView.as_view()),
    re_path(r'^userinfo/$', views.UserInfoView.as_view()),
    re_path(r'^group/(?P<pk>\d+)$', views.GroupView.as_view(), name='gp'), #注意这里的pk,默认系统里面这么写的,可以在view中改掉.,源码在: class HyperlinkedRelatedField(RelatedField): lookup_field = 'pk' 这个pk就是人家默认规定的就是这个pk,但是pk不对,因为pk是id,id是变化的,二分组是固定的.
    re_path(r'^usergroup/$', views.UserGroupView.as_view()),
    re_path(r'^page1/$', views.Page1View.as_view()), #这个是测试分页的功能的时候的URL
    re_path(r'^page2/$', views.Page1View_2.as_view()), #这个是测试分页的功能的时候的URL
    re_path(r'^page3/$', views.Page1View_3.as_view()), #这个是测试分页的功能的时候的URL
    re_path(r'^v1/$', views.V1View.as_view()), #这个是测试restframework View视图功能的时候的URL
    re_path(r'^v2/$', views.V2View.as_view({'get': 'xxx'})), #这里V2View()继承了GenericViewSet,这个类重写了as_view()方法,需要传递action方法

    #这里V3View()继承了ModelViewSet, ModelViewSet又继承了GenericViewSet(),然后GenericViewSet重写了as_view()方法,所以我们自定义的类视图继承了ModelViewSet()类
    #也要改写url中的as_view(),给他传递参数.
    # 首先这个一一对应就需要查询源码了,源码里面有具体的函数名字.
    re_path(r'^v3/$', views.V3View.as_view({'get': 'list', 'post':'create'})), # 注意这个url的前半部分,没有写那个pk,什么意思,表示get请求的是全部的数据,post请求不需要指定的pk,直接就可以朝数据库中传递对应的字段,
    # 注意下面的url,这个里面的pk\d+表示针对的是数据库中的一个数据,不再是整体了,对一个数据操作,看一下各自对应的方法.记得不要写错.就可以实现一一对应增删改查的功能
    re_path(r'^v3/(?P<pk>\d+)/$', views.V3View.as_view({'get': 'retrieve', 'delete':'destroy', 'put':'update', 'patch':'partial_update'})),


    #'''
    #下面的代码是路由系统,自动生成的路由
    #为什么需要系统自动生成url,因为针对一个视图,一般会有2个url,因为是获取的整体和单独的一个数据的原因,那么再加上json格式的缘故,就会有一个
    #视图生成了4个url,那么如果觉得自己写的很麻烦,可以在这里设置一些,让系统自己帮你生成
    #'''
    # url(r'(?P<version>)[v1|v2]/$', include(router.urls)),带有版本前缀的写法.
    url(r'^', include(router.urls)), #这里一定要用url(),re_path 和path 不行.



    #下面的url是用来测试渲染器的
    url(r'^test/$', views.TestView.as_view())

]

1.2 models.py 文件内容如下,新建数据表

from django.db import models

class UserInfo(models.Model):
    user_type_choices = (
        (1, '普通用户'),
        (2, 'VIP客户'),
        (3, 'SVIP')
    )
    user_type = models.IntegerField(choices=user_type_choices)

    username = models.CharField(max_length=32, unique=True)
    password = models.CharField(max_length=64)

    group = models.ForeignKey(to='UserGroup', on_delete=models.CASCADE) # 假设一个组对应多个人,一个人只有多个组
    roles = models.ManyToManyField('Role')

class UserGroup(models.Model):
    title = models.CharField(max_length=32)

class Role(models.Model):
    title = models.CharField(max_length=32)

1.3 views.py 文件编写, 写serializer 序列化和反序列化

#######################django rest framework 视图功能#############################################
'''
直接一步到位的说, 这个视图类里面的继承关系,越往下继承功能越多,而且系统也帮我们实现了基于view的增删改查,都是基于mixin的类操作,如下总价:
继承链1:
1, View -> APIView -> GenericAPIView -> [CreateAPIView(mixins.CreateModelMixin,
                    GenericAPIView), ListAPIView, RetrieveAPIView, DestroyAPIView, UpdateAPIView, ListCreateAPIView, RetrieveUpdateAPIView, RetrieveDestroyAPIView, RetrieveUpdateDestroyAPIView]
                    
继承链2:
2, View -> APIView -> GenericAPIView -> GenericViewSet(ViewSetMixin, generics.GenericAPIView) -> class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet)
实际上,2个继承链,继承到最后,都各自实现了, 增删改查的功能, 但是实现的方式是类或者是Mixin的方式, 而且这里还做了一个一一对应的关系,改写了get, post put, patch的,使这些普通的方式变成了对应的, List, create, update, delete等对应的类或者Mixin.
这里改写之后,同理就要改变那个url中path,因为get, post. 找不到对应的函数了,所以在url中的as_view()函数中,就要填入相应的参数,就要把一一对应的,比如说: get->list, post->create, put->update等参数按照字典的方式传递进去.
同时path里面的url要写两个,一个使对整体的,一个是对整体中的一个的,比如说:
re_path(r'^viewtest/$', ViewTest.as_view({'get':'list', 'post':'create'}) ->这个是针对整个数据库进行操作
re_path(r'^viewtest/(?P<pk>\d+)/$', ViewTest.as_view({'get':'retrieve', 'delete':'destroy', 'put':'update', 'patch':'partial_update'}) -> 这个是针对数据库里面的一个单独的数据操作,可以看到(?P<pk>\d+)这个就是单独的一个实例操作.

使用ModelViewSet()这个类,URL也可以自动生成,就是rest framework 连这个部分都给我们搞定了,真的是保姆基本的框架.
'''


# 1, 以下示例 GenericAPIView: 不实用
from rest_framework.generics import GenericAPIView #查看源码,可以看到GenericAPIView 继承我们之前一直写的APIView()
'''
这个GenericAPIView()里面都是get_方法,这些方法 都是实现之前一直说的序列化,分页功能,只不过这里都搞成自己的字段了,这个类
其实不好用,并不比我们之前单独写的serializer()类, pagination()类,自己去实例化,去分页省事,所以这个可以不用,不如继承APIView
'''
class V1View(GenericAPIView):
    def get(self, request, *args, **kwargs):
        return Response()



# 2, 以下示例 GenericViewSet
from rest_framework.viewsets import GenericViewSet #看源码,这个类重写了as_view()方法,而且需要传递参数进去,所以那个URL中需要传递参数就可以理解,一对一的get->list, post->create等. 或者映射到系统里面的写好的Mixin方法.
class V2View(GenericViewSet):
    #这里继承的GenericViewSet 重写了as_view()方法, 所以在url中要传参,传递字典,是get->list,然后这个list还要在这里写一个list函数. 当然这里的list名字是可以改变的,可以改成xxx,同时url中对应的字典也要改成xxx
    def xxx(self, request, *args, **kwargs):

        return Response('xx')

# 3, 以下示例 ModelViewSet
from rest_framework.viewsets import ModelViewSet #看源码这个类继承了好多Mixin 和上面的GenericViewSet(),所以继承了上面的所有方法,同时也需要设置的东西也很多
class Page_3Serializer(serializers.ModelSerializer):
    class Meta:
        model = Role
        fields = "__all__"

class V3View(ModelViewSet):
    '''
    这个类继承了ModelViewSet(), ModelViewSet()又继承了很多Mixin和GenericViewSet(),所以根据源码
    这里仅仅要设置: 咱们要操作的数据表,就是那个queryset
                要序列化那个数据表,就是那个serializer_class
                要使用哪一个分页的类, 就是那个pagination_class
                就是下面设置的三个属性.只要设定了下面的三个属性,然后在url中,写上想要的方法 对应字典,就可以完成基本的增删改查操作了.
    '''
    queryset = Role.objects.all()
    serializer_class = Page_3Serializer
    pagination_class = PageNumberPagination

    '''
    部分总结: 如果你想要的功能越来越多,就可以自定义视图的时候,向下继承,比如ModelViewSet()这个功能多,什么都有.
            如果你想自己实现一些增删改查的功能的时候,你就继承APIView(), 这个更接近View类,需要自己实现很多功能
    这里请注意: 这里例子3,继承了ModelViewSet() 那么请注意url哪里首先要一一对象方法名,第二个就是一个视图要写两个URL, 一个是用来针对整体的
            一个是用来针对一个数据的. 如果你没有继承这个类,那么如何区分前端传入的请求,比如get请求,是针对整体的还是一个数据的,需要在kwargs里面判断
            如果传递了id那么就是一个数据,如果没有传,那么就是整个的.
    
    使用范围总结:
            a, 想要增删改查: 继承 ModelViewSet()
            b, 想要增删: 继承 CreateModelMixin, DestroyModelMixin, GenericViewSet
            c, 想要复杂逻辑: 继承 GenericViewSet 或 APIView
        
    
    下面和路由系统URL一起总结.
    '''
    #########View######视图#######结束
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值