1, 先写一个APP, 名字叫dsj
1.1 urls.py文件内容如下:
from django.urls import path, re_path, include
from django.conf.urls import url
from . import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register(prefix=r'xxx', viewset=views.V3View)
router.register(prefix=r'rt', viewset=views.V3View)
urlpatterns = [
re_path(r'^roles/$', views.RolesView.as_view()),
re_path(r'^userinfo/$', views.UserInfoView.as_view()),
re_path(r'^group/(?P\d+)$', views.GroupView.as_view(), name='gp'),
re_path(r'^usergroup/$', views.UserGroupView.as_view()),
re_path(r'^page1/$', views.Page1View.as_view()),
re_path(r'^page2/$', views.Page1View_2.as_view()),
re_path(r'^page3/$', views.Page1View_3.as_view()),
re_path(r'^v1/$', views.V1View.as_view()),
re_path(r'^v2/$', views.V2View.as_view({'get': 'xxx'})),
re_path(r'^v3/$', views.V3View.as_view({'get': 'list', 'post':'create'})),
re_path(r'^v3/(?P\d+)/$', views.V3View.as_view({'get': 'retrieve', 'delete':'destroy', 'put':'update', 'patch':'partial_update'})),
url(r'^', include(router.urls)),
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 序列化和反序列化
'''
直接一步到位的说, 这个视图类里面的继承关系,越往下继承功能越多,而且系统也帮我们实现了基于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\d+)/$', ViewTest.as_view({'get':'retrieve', 'delete':'destroy', 'put':'update', 'patch':'partial_update'}) -> 这个是针对数据库里面的一个单独的数据操作,可以看到(?P\d+)这个就是单独的一个实例操作.
使用ModelViewSet()这个类,URL也可以自动生成,就是rest framework 连这个部分都给我们搞定了,真的是保姆基本的框架.
'''
from rest_framework.generics import GenericAPIView
'''
这个GenericAPIView()里面都是get_方法,这些方法 都是实现之前一直说的序列化,分页功能,只不过这里都搞成自己的字段了,这个类
其实不好用,并不比我们之前单独写的serializer()类, pagination()类,自己去实例化,去分页省事,所以这个可以不用,不如继承APIView
'''
class V1View(GenericAPIView):
def get(self, request, *args, **kwargs):
return Response()
from rest_framework.viewsets import GenericViewSet
class V2View(GenericViewSet):
def xxx(self, request, *args, **kwargs):
return Response('xx')
from rest_framework.viewsets import ModelViewSet
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一起总结.
'''