一 视图集与路由的使用

使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:

list() 提供一组数据

retrieve() 提供单个数据

create() 创建数据

update() 保存数据

destory() 删除数据

ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。

视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。

1.1 常用的视图集父类

1 ViewSet

继承自APIView 与 ViewSetMixin作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。

ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{'get':'list'})的映射处理工作。

在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。

2 GenericViewSet

使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView。

GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView与ViewSetMixin,在实现了调用as_view()时传入字典(如{'get':'list'})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。

3.ModelViewSet

继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

4.ReadOnlyModelViewSet

继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。

1.2 视图集初步使用

创建一个子应用app

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py startapp collect

注册

INSTALLED_APPS =['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework','students.apps.StudentsConfig','ser.apps.SerConfig','req.apps.ReqConfig','collect.apps.CollectConfig',

]

路由分发

from django.contrib importadminfrom django.urls importpath,include

urlpatterns=[

path('admin/', admin.site.urls),

path('student/',include("students.urls")),

path('ser/',include("ser.urls")),

path('req/', include("req.urls")),

path('collect/', include("collect.urls")),

]

路由配置

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/urls.py

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

]

序列化文件

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/serializers.py

from students.models importStudentfrom rest_framework importserializersclassStudentModelSerializer(serializers.ModelSerializer):classMeta:

model=Student

fields= ["id", "name", "age", "sex"]

extra_kwargs={"name": {"max_length": 10, "min_length": 4},"age": {"max_value": 150, "min_value": 0},

}defvalidate_name(self, data):if data == "root":raise serializers.ValidationError("用户名不能为root!")returndatadefvalidate(self, attrs):

name= attrs.get('name')

age= attrs.get('age')if name == "alex" and age == 22:raise serializers.ValidationError("alex在22时的故事。。。")return attrs

视图文件

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)return Response(serializer.data)

访问http://127.0.0.1:8000/collect/student1/可以获取五条数据

数据库中数据

mysql> select * from tb_student;

修改id=5的sex为false

数据库现有数据

获取5个男性的数据

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)return Response(serializer.data)

配置路由

不要在同一个路由的as_view中书写两个同样的键的http请求,会产生覆盖!!!

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

]

访问http://127.0.0.1:8000/collect/student1/get_5_female/结果如下

获取一条

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),

]

配置视图

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)return Response(serializer.data)

POSTMAN调试,访问http://127.0.0.1:8000/collect/student1/5/

GenericViewSet视图

URL路由配置

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),#GenericViewSet

path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),

path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),

]

视图文件

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)return Response(serializer.data)

POSTMAN调试

1.3 GenericViewSet结合模型类

可以和模型类进行组合快速生成基本的API接口

url路由配置

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),#GenericViewSet

path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),

path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),#GenericViewSet和模型类进行组合快速生成基本的API接口,当使用get,触发list的方法,当使用POST请求,触发create方法

path("students3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),

]

视图文件

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)from rest_framework.mixins importListModelMixin, CreateModelMixinclassStudent4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):

queryset=Student.objects.all()

serializer_class= StudentModelSerializer

POSTMAN调试

get请求

POST请求

查看数据库

1.4 ModelViewSet配置

url配置

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),#GenericViewSet

path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),

path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),#GenericViewSet和模型类进行组合快速生成基本的API接口

path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),#ModelViewSet 默认提供了5个API接口

path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),

re_path(r"^student4/(?P\d+)/$",

views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

]

views

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)from rest_framework.mixins importListModelMixin, CreateModelMixinclassStudent4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importModelViewSetclassStudent5ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class= StudentModelSerializer

POSTMAN调试

获取所有

POST添加

数据库

PUT修改

数据库

delete删除

数据库

mysql> select * fromtb_student;+----+------------+-----+-----+------------+-------------------+

| id | name | sex | age | class_null | description |

+----+------------+-----+-----+------------+-------------------+

| 1 | 令狐冲 | 1 | 18 | 205 | hello mysqlf |

| 2 | 任我行 | 1 | 55 | 203 | hello let me go |

| 3 | 李寻欢 | 1 | 33 | 207 | be happy lee |

| 5 | limochu | 0 | 36 | 208 | Don’t Worry Lee |

| 6 | mchaofeng | 1 | 26 | | |

| 7 | yangguo | 1 | 25 | | |

| 8 | xiaolongnv | 0 | 25 | | |

+----+------------+-----+-----+------------+-------------------+

1.5 ReadOnlyModelViewSet配置

url路由配置

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),#GenericViewSet

path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),

path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),#GenericViewSet和模型类进行组合快速生成基本的API接口

path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),#ModelViewSet 默认提供了5个API接口

path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),

re_path(r"^student4/(?P\d+)/$",

views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),#ReadOnlyModelViewSet

path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),

re_path(r"^student5/(?P\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),

]

view视图配置

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)from rest_framework.mixins importListModelMixin, CreateModelMixinclassStudent4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importModelViewSetclassStudent5ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importReadOnlyModelViewSetclassStudent6ReadOnlyModelViewSet(ReadOnlyModelViewSet):

queryset=Student.objects.all()

serializer_class= StudentModelSerializer

只有get方法

获取一条

二 路由类的使用

有了视图集以后,视图文件中多个视图类可以合并成一个,但是,路由的代码就变得复杂了, 需要我们经常在as_view方法 ,编写http请求和视图方法的对应关系, 事实上,在路由中,DRF也提供了一个路由类给我们对路由的代码进行简写。 当然,这个路由类仅针对于 视图集 才可以使用。

2.1 路由类基本配置

url路由配置

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),#GenericViewSet

path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),

path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),#GenericViewSet和模型类进行组合快速生成基本的API接口

path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),#ModelViewSet 默认提供了5个API接口

path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),

re_path(r"^student4/(?P\d+)/$",

views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),#ReadOnlyModelViewSet

path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),

re_path(r"^student5/(?P\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),

]#路由类默认只会给视图集中的基本5个API生成地址[ 获取一条,获取多条,添加.删除,修改数据 ]

from rest_framework.routers importDefaultRouter#实例化路由类

router =DefaultRouter()#router.register("访问地址前缀","视图集类","访问别名")#注册视图视图集类

router.register("student7", views.Student7ModelViewSet)print(router.urls)#把路由列表注册到django项目中

urlpatterns += router.urls

views视图文件

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)from rest_framework.mixins importListModelMixin, CreateModelMixinclassStudent4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets import ModelViewSet

class Student5ModelViewSet(ModelViewSet):

queryset = Student.objects.all()

serializer_class = StudentModelSerializerfrom rest_framework.viewsets importReadOnlyModelViewSetclassStudent6ReadOnlyModelViewSet(ReadOnlyModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.decorators importactionclassStudent7ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class= StudentModelSerializer

重启之后,查看print打印内容

[

,

[a-z0-9]+)/?$' [name='student-list']>,

[^/.]+)/$' [name='student-detail']>,

[^/.]+)\.(?P[a-z0-9]+)/?$' [name='student-detail']>,

,

[a-z0-9]+)/?$' [name='api-root']>

]

POSTMAN调试

获取所有

2.2 自定义方法并调用

添加进views方法中

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)from rest_framework.mixins importListModelMixin, CreateModelMixinclassStudent4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importModelViewSetclassStudent5ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importReadOnlyModelViewSetclassStudent6ReadOnlyModelViewSet(ReadOnlyModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.decorators importactionclassStudent7ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer#methods 指定允许哪些http请求访问当前视图方法

#detail 指定生成的路由地址中是否要夹带pk值,True为需要

#@action(methods=['get'], detail=False)

#def get_4(self, request):

@action(methods=['get'], detail=True)

def get_5(self, request, pk):

serilizer = self.get_serializer(instance=self.get_queryset().get(pk=pk))

return Response(serilizer.data)

重启查看打印信息

[

,

[a-z0-9]+)/?$' [name='student-list']>,

[^/.]+)/$' [name='student-detail']>,

[^/.]+)\.(?P[a-z0-9]+)/?$' [name='student-detail']>,

[^/.]+)/get_5/$' [name='student-get-5']>,

[^/.]+)/get_5\.(?P[a-z0-9]+)/?$' [name='student-get-5']>,

,

[a-z0-9]+)/?$' [name='api-root']>]

POSTMAN访问自定义方法

2.3 在一个视图类调用多个视图划器类

url路由配置

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),#GenericViewSet

path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),

path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),#GenericViewSet和模型类进行组合快速生成基本的API接口

path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),#ModelViewSet 默认提供了5个API接口

path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),

re_path(r"^student4/(?P\d+)/$",

views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),#ReadOnlyModelViewSet

path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),

re_path(r"^student5/(?P\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),#一个视图类中调用多个序列化器

path("student8/", views.Student8GenericAPIView.as_view()),

]#路由类默认只会给视图集中的基本5个API生成地址[ 获取一条,获取多条,添加.删除,修改数据 ]

from rest_framework.routers importDefaultRouter#实例化路由类

router =DefaultRouter()#router.register("访问地址前缀","视图集类","访问别名")#注册视图视图集类

router.register("student7", views.Student7ModelViewSet)print(router.urls)#把路由列表注册到django项目中

urlpatterns += router.urls

view视图配置

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)from rest_framework.mixins importListModelMixin, CreateModelMixinclassStudent4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importModelViewSetclassStudent5ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importReadOnlyModelViewSetclassStudent6ReadOnlyModelViewSet(ReadOnlyModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.decorators importactionclassStudent7ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer#methods 指定允许哪些http请求访问当前视图方法

#detail 指定生成的路由地址中是否要夹带pk值,True为需要

#@action(methods=['get'], detail=False)

#def get_4(self, request):

@action(methods=['get'], detail=True)defget_5(self, request, pk):

serilizer= self.get_serializer(instance=self.get_queryset().get(pk=pk))returnResponse(serilizer.data)from rest_framework.generics importGenericAPIViewfrom collect.serializers importStudentInfoModelSerializerclassStudent8GenericAPIView(GenericAPIView):

queryset=Student.objects.all()#GenericAPI内部调用序列化器的方法,我们可以重写这个方法来实现根据不同的需求来调用不同的序列化器

defget_serializer_class(self):if self.request.method == "GET":#2个字段

returnStudentInfoModelSerializerreturnStudentModelSerializerdefget(self, request):"""获取所有数据的id和name"""student_list=self.get_queryset()

serializer= self.get_serializer(instance=student_list, many=True)#serializer = StudentInfoModelSerializer(instance=student_list, many=True)

returnResponse(serializer.data)defpost(self, request):"""添加数据"""data=request.data

serializer= self.get_serializer(data=data)

serializer.is_valid(raise_exception=True)

serializer.save()return Response(serializer.data)

序列化类

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim collect/serializers.py

from students.models importStudentfrom rest_framework importserializersclassStudentModelSerializer(serializers.ModelSerializer):classMeta:

model=Student

fields= ["id", "name", "age", "sex"]

extra_kwargs={"name": {"max_length": 10, "min_length": 4},"age": {"max_value": 150, "min_value": 0},

}defvalidate_name(self, data):if data == "root":raise serializers.ValidationError("用户名不能为root!")returndatadefvalidate(self, attrs):

name= attrs.get('name')

age= attrs.get('age')if name == "alex" and age == 22:raise serializers.ValidationError("alex在22时的故事。。。")returnattrsclassStudentInfoModelSerializer(serializers.ModelSerializer):classMeta:

model=Student

fields= ["id", "name"]

访问http://127.0.0.1:8000/collect/student8/

只有两个字段

2.4 视图集内使用多个序列化类

url配置

from django.urls importpath,re_pathfrom collect importviews

urlpatterns=[#ViewSet

path('student1/', views.Student1ViewSet.as_view({"get": "get_5"})),

path('student1/get_5_female/', views.Student1ViewSet.as_view({"get": "get_5_female"})),

re_path(r'^student1/(?P\d+)/$', views.Student1ViewSet.as_view({"get": "get_one"})),#GenericViewSet

path('student2/', views.Student3GenericViewSet.as_view({"get": "get_5"})),

path('student2/get_5_female/', views.Student3GenericViewSet.as_view({"get": "get_5_female"})),#GenericViewSet和模型类进行组合快速生成基本的API接口

path("student3/", views.Student4GenericViewSet.as_view({"get": "list", "post": "create"})),#ModelViewSet 默认提供了5个API接口

path("student4/", views.Student5ModelViewSet.as_view({"post": "create", "get": "list"})),

re_path(r"^student4/(?P\d+)/$",

views.Student5ModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),#ReadOnlyModelViewSet

path("student5/", views.Student6ReadOnlyModelViewSet.as_view({"get": "list"})),

re_path(r"^student5/(?P\d+)/$", views.Student6ReadOnlyModelViewSet.as_view({"get": "retrieve"})),#一个视图类中调用多个序列化器

path("student8/", views.Student8GenericAPIView.as_view()),#一个视图集中调用多个序列化器

path("student9/", views.Student9ModelViewSet.as_view({"get": "list"})),

re_path(r"^student9/(?P\d+)/$", views.Student9ModelViewSet.as_view({"get": "retrieve"})),

]#路由类默认只会给视图集中的基本5个API生成地址[ 获取一条,获取多条,添加.删除,修改数据 ]

from rest_framework.routers importDefaultRouter#实例化路由类

router =DefaultRouter()#router.register("访问地址前缀","视图集类","访问别名")#注册视图视图集类

router.register("student7", views.Student7ModelViewSet)print(router.urls)#把路由列表注册到django项目中

urlpatterns += router.urls

views配置

要求:

列表数据list,返回2个字段,

详情数据retrieve,返回所有字段

from django.shortcuts importrenderfrom rest_framework.viewsets importViewSetfrom students.models importStudentfrom collect.serializers importStudentModelSerializerfrom rest_framework.response importResponse#Create your views here.

classStudent1ViewSet(ViewSet):defget_5(self,request):#取出所有,并切片操作

queryset = Student.objects.all()[:5]#实例化

serializer = StudentModelSerializer(instance=queryset,many=True)returnResponse(serializer.data)defget_5_female(self,request):

queryset= Student.objects.filter(sex=False)[:5]

serializer= StudentModelSerializer(instance=queryset, many=True)returnResponse(serializer.data)defget_one(self,request,pk):

student_obj= Student.objects.get(pk=pk)

serializer= StudentModelSerializer(instance=student_obj)returnResponse(serializer.data)from rest_framework.viewsets importGenericViewSetclassStudent3GenericViewSet(GenericViewSet):

serializer_class=StudentModelSerializer

queryset=Student.objects.all()defget_5(self, request):

student_list= self.get_queryset()[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)defget_5_female(self, request):

student_list= self.get_queryset().filter(sex=False)[:5]

serializer= self.get_serializer(instance=student_list, many=True)returnResponse(serializer.data)from rest_framework.mixins importListModelMixin, CreateModelMixinclassStudent4GenericViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importModelViewSetclassStudent5ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.viewsets importReadOnlyModelViewSetclassStudent6ReadOnlyModelViewSet(ReadOnlyModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializerfrom rest_framework.decorators importactionclassStudent7ModelViewSet(ModelViewSet):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer#methods 指定允许哪些http请求访问当前视图方法

#detail 指定生成的路由地址中是否要夹带pk值,True为需要

#@action(methods=['get'], detail=False)

#def get_4(self, request):

@action(methods=['get'], detail=True)defget_5(self, request, pk):

serilizer= self.get_serializer(instance=self.get_queryset().get(pk=pk))returnResponse(serilizer.data)from rest_framework.generics importGenericAPIViewfrom collect.serializers importStudentInfoModelSerializerclassStudent8GenericAPIView(GenericAPIView):

queryset=Student.objects.all()#GenericAPI内部调用序列化器的方法,我们可以重写这个方法来实现根据不同的需求来调用不同的序列化器

defget_serializer_class(self):if self.request.method == "GET":#2个字段

returnStudentInfoModelSerializerreturnStudentModelSerializerdefget(self, request):"""获取所有数据的id和name"""student_list=self.get_queryset()

serializer= self.get_serializer(instance=student_list, many=True)#serializer = StudentInfoModelSerializer(instance=student_list, many=True)

returnResponse(serializer.data)defpost(self, request):"""添加数据"""data=request.data

serializer= self.get_serializer(data=data)

serializer.is_valid(raise_exception=True)

serializer.save()returnResponse(serializer.data)classStudent9ModelViewSet(ModelViewSet):

queryset=Student.objects.all()defget_serializer_class(self):#本次客户端请求的视图方法名 self.action

print(self.action)if self.action == "list":returnStudentInfoModelSerializerreturn StudentModelSerializer

get获取所有,只返回两个字段

打印的结果是list

输出单个信息,会输出4个字段

方法名称

三  DRF的扩展功能

创建新的app应用

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py startapp opt

注册

INSTALLED_APPS =['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework','students.apps.StudentsConfig','ser.apps.SerConfig','req.apps.ReqConfig','collect.apps.CollectConfig','opt.apps.OptConfig',

]

配置字体

LANGUAGE_CODE = 'zh-hans'

添加路由分发

from django.contrib importadminfrom django.urls importpath,include

urlpatterns=[

path('admin/', admin.site.urls),

path('student/',include("students.urls")),

path('ser/',include("ser.urls")),

path('req/', include("req.urls")),

path('collect/', include("collect.urls")),

path('opt/', include("opt.urls")),

]

3.1 用户控制

创建路由文件

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim opt/urls.py

from django.urls importpathfrom opt importviews

urlpatterns=[

path('auth1/', views.Demo1APIView.as_view()),

path('auth2/', views.Demo2APIView.as_view()),]

views文件

from django.shortcuts importrender#Create your views here.

from rest_framework.views importAPIViewfrom rest_framework.response importResponsefrom rest_framework.permissions importIsAuthenticated, IsAdminUser#用户的认证和权限识别

classDemo1APIView(APIView):#只允许登录后的用户访问

permission_classes =[IsAuthenticated]defget(self, request):#个人中心

return Response("个人中心")classDemo2APIView(APIView):#只允许管理员访问

permission_classes =[IsAdminUser]defget(self, request):#个人中心2

return Response("个人中心2")

创建一个admin用户进行管理

创建一个alex用户

使用alex登录,同时取消人员状态

必须是一个超级管理员用户才能看见

查看数据的seeeion

mysql> select * from django_session;

+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+

| session_key | session_data | expire_date |

+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+

| fn55zqveedvfjckalewwusqny7iadhun | MWM5NDBiNmI0ZDZlYTFmZmM4MjE4YTkyODcyMWNmNTQ4NjJkNDJkNTp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiIwMTY2ZDUxMTFhYzU2ZTBjMWRkZDU5ZmM3MmE5ZmI1ZjcyYWY4NmMxIn0= | 2020-05-05 07:27:10.353593 |

+----------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------+

3.2 权限Permissions控制

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

在执行视图的dispatch()方法前,会先进行视图访问权限的判断

在通过get_object()获取具体对象时,会进行模型对象访问权限的判断

内置提供的权限:

AllowAny 允许所有用户

IsAuthenticated 仅通过认证的用户

IsAdminUser 仅管理员用户

IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。

可以在配置文件中全局设置默认的权限管理类,如:

REST_FRAMEWORK ={

....'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',

)

}

如果未指明,则采用如下默认配置

'DEFAULT_PERMISSION_CLASSES': (

'rest_framework.permissions.AllowAny',

自定义权限

url配置

from django.urls importpath,re_pathfrom opt importviews

urlpatterns=[

path('auth1/', views.Demo1APIView.as_view()),

path('auth2/', views.Demo2APIView.as_view()),#自定义权限

path('auth3/', views.Demo3APIView.as_view()),

]

views配置

from django.shortcuts importrender#Create your views here.

from rest_framework.views importAPIViewfrom rest_framework.response importResponsefrom rest_framework.permissions importIsAuthenticated, IsAdminUser#用户的认证和权限识别

classDemo1APIView(APIView):#只允许登录后的用户访问

permission_classes =[IsAuthenticated]defget(self, request):#个人中心

return Response("个人中心")classDemo2APIView(APIView):#只允许管理员访问

permission_classes =[IsAdminUser]defget(self, request):#个人中心2

return Response("个人中心2")#自定义权限

from rest_framework.permissions importBasePermissionclassMyPermission(BasePermission):defhas_permission(self, request, view):"""针对访问视图进行权限判断

:param request: 本次操作的http请求对象

:param view: 本次访问路由对应的视图对象

:return:"""

if request.user.username == "xiaoming":returnTruereturnFalseclassDemo3APIView(APIView):

permission_classes=[MyPermission]defget(self, request):"""个人中心3"""

return Response("个人中心3")

创建xiaoming用户

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# python3 manage.py createsuperuser

使用root登录访问auth3

使用ixaoming用户登录访问

3.3  限流Throttling

可以对接口访问的频次进行限制,以减轻服务器压力。

一般用于付费购买次数,投票等场景使用.

可以在配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES进行全局配置

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# vim drf_demo/settings.py

REST_FRAMEWORK ={#限流

'DEFAULT_THROTTLE_CLASSES': ( #对全局进行设置

'rest_framework.throttling.AnonRateThrottle','rest_framework.throttling.UserRateThrottle'),'DEFAULT_THROTTLE_RATES': {'anon': '3/hour','user': '3/minute',

}

}

DEFAULT_THROTTLE_RATES 可以使用 second, minute, hour 或day来指明周期。

URL文件

from django.urls importpath,re_pathfrom opt importviews

urlpatterns=[

path('auth1/', views.Demo1APIView.as_view()),

path('auth2/', views.Demo2APIView.as_view()),#自定义权限

path('auth3/', views.Demo3APIView.as_view()),#限流

path('auth4/', views.Demo4APIView.as_view()),

]

views视图文件

from django.shortcuts importrender#Create your views here.

from rest_framework.views importAPIViewfrom rest_framework.response importResponsefrom rest_framework.permissions importIsAuthenticated, IsAdminUser#用户的认证和权限识别

classDemo1APIView(APIView):#只允许登录后的用户访问

permission_classes =[IsAuthenticated]defget(self, request):#个人中心

return Response("个人中心")classDemo2APIView(APIView):#只允许管理员访问

permission_classes =[IsAdminUser]defget(self, request):#个人中心2

return Response("个人中心2")#自定义权限

from rest_framework.permissions importBasePermissionclassMyPermission(BasePermission):defhas_permission(self, request, view):"""针对访问视图进行权限判断,必须使用xiaoming用户

:param request: 本次操作的http请求对象

:param view: 本次访问路由对应的视图对象

:return:"""

if request.user.username == "xiaoming":returnTruereturnFalseclassDemo3APIView(APIView):

permission_classes=[MyPermission]defget(self, request):"""个人中心3"""

return Response("个人中心3")#限流

from rest_framework.throttling importUserRateThrottle, AnonRateThrottleclassDemo4APIView(APIView):

throttle_classes= [UserRateThrottle, AnonRateThrottle] #全局配置后,这里就不用指定

defget(self, request):"""投票页面"""

return Response("投票页面")

访问auth4

当超过3次

注销用户,使用匿名用户次数超标

3.4  过滤Filtering

对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

安装django-filter

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# pip3 install django-filter

注册

INSTALLED_APPS =['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework','django_filters', #需要注册应用,

'students.apps.StudentsConfig','ser.apps.SerConfig','req.apps.ReqConfig','collect.apps.CollectConfig','opt.apps.OptConfig',

]

配置url路由

from django.urls importpath,re_pathfrom opt importviews

urlpatterns=[

path('auth1/', views.Demo1APIView.as_view()),

path('auth2/', views.Demo2APIView.as_view()),#自定义权限

path('auth3/', views.Demo3APIView.as_view()),#限流

path('auth4/', views.Demo4APIView.as_view()),#过滤

path('data5/', views.Demo5APIView.as_view()),

]

views视图

from django.shortcuts importrender#Create your views here.

from rest_framework.views importAPIViewfrom rest_framework.response importResponsefrom rest_framework.permissions importIsAuthenticated, IsAdminUser#用户的认证和权限识别

classDemo1APIView(APIView):#只允许登录后的用户访问

permission_classes =[IsAuthenticated]defget(self, request):#个人中心

return Response("个人中心")classDemo2APIView(APIView):#只允许管理员访问

permission_classes =[IsAdminUser]defget(self, request):#个人中心2

return Response("个人中心2")#自定义权限

from rest_framework.permissions importBasePermissionclassMyPermission(BasePermission):defhas_permission(self, request, view):"""针对访问视图进行权限判断,必须使用xiaoming用户

:param request: 本次操作的http请求对象

:param view: 本次访问路由对应的视图对象

:return:"""

if request.user.username == "xiaoming":returnTruereturnFalseclassDemo3APIView(APIView):

permission_classes=[MyPermission]defget(self, request):"""个人中心3"""

return Response("个人中心3")#限流

from rest_framework.throttling importUserRateThrottle, AnonRateThrottleclassDemo4APIView(APIView):

throttle_classes= [UserRateThrottle, AnonRateThrottle] #全局配置后,这里就不用指定

defget(self, request):"""投票页面"""

return Response("投票页面")#过滤

from rest_framework.generics importGenericAPIView, ListAPIViewfrom students.models importStudentfrom opt.serializers importStudentModelSerializerfrom django_filters.rest_framework importDjangoFilterBackend#'django_filters.rest_framework.DjangoFilterBackend'

classDemo5APIView(ListAPIView):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer

filter_backends= [DjangoFilterBackend] #全局配置后,这里就不用指定了。

filter_fields = ['age', "id"] #声明过滤字段

复制一个序列化类

(drfdemo) root@darren-virtual-machine:~/PycharmProjects/drfdemo/drf_demo# cp collect/serializers.py     opt/

setting设置

REST_FRAMEWORK ={#限流

'DEFAULT_THROTTLE_CLASSES': ( #对全局进行设置

'rest_framework.throttling.AnonRateThrottle','rest_framework.throttling.UserRateThrottle'),'DEFAULT_THROTTLE_RATES': {'anon': '3/hour','user': '3/minute',

}'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)

}

点击过滤器

提交

3.5 排序Ordering

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

使用方法:

在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。

前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

路由配置

from django.urls importpath,re_pathfrom opt importviews

urlpatterns=[

path('auth1/', views.Demo1APIView.as_view()),

path('auth2/', views.Demo2APIView.as_view()),#自定义权限

path('auth3/', views.Demo3APIView.as_view()),#限流

path('auth4/', views.Demo4APIView.as_view()),#过滤

path('data5/', views.Demo5APIView.as_view()),#排序

path('data6/', views.Demo6APIView.as_view()),

]

views视图配置

from django.shortcuts importrender#Create your views here.

from rest_framework.views importAPIViewfrom rest_framework.response importResponsefrom rest_framework.permissions importIsAuthenticated, IsAdminUser#用户的认证和权限识别

classDemo1APIView(APIView):#只允许登录后的用户访问

permission_classes =[IsAuthenticated]defget(self, request):#个人中心

return Response("个人中心")classDemo2APIView(APIView):#只允许管理员访问

permission_classes =[IsAdminUser]defget(self, request):#个人中心2

return Response("个人中心2")#自定义权限

from rest_framework.permissions importBasePermissionclassMyPermission(BasePermission):defhas_permission(self, request, view):"""针对访问视图进行权限判断,必须使用xiaoming用户

:param request: 本次操作的http请求对象

:param view: 本次访问路由对应的视图对象

:return:"""

if request.user.username == "xiaoming":returnTruereturnFalseclassDemo3APIView(APIView):

permission_classes=[MyPermission]defget(self, request):"""个人中心3"""

return Response("个人中心3")#限流

from rest_framework.throttling importUserRateThrottle, AnonRateThrottleclassDemo4APIView(APIView):

throttle_classes= [UserRateThrottle, AnonRateThrottle] #全局配置后,这里就不用指定

defget(self, request):"""投票页面"""

return Response("投票页面")#过滤

from rest_framework.generics importGenericAPIView, ListAPIViewfrom students.models importStudentfrom opt.serializers importStudentModelSerializerfrom django_filters.rest_framework importDjangoFilterBackend#'django_filters.rest_framework.DjangoFilterBackend'

classDemo5APIView(ListAPIView):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer

filter_backends= [DjangoFilterBackend] #全局配置后,这里就不用指定了。

filter_fields = ['age', "id"] #声明过滤字段

#排序

from rest_framework.filters importOrderingFilterclassDemo6APIView(ListAPIView):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer

filter_backends= [DjangoFilterBackend, OrderingFilter] #局部配置会覆盖全局配置

filter_fields = ['id', "sex"]

ordering_fields= ['id', "age"]

点击过滤器

3.6 分页Pagination

REST framework提供了分页的支持。

我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK ={'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination','PAGE_SIZE': 100 #每页数目

}

也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明。

opt下的urls.py

from django.urls importpath,re_pathfrom opt importviews

urlpatterns=[

path('auth1/', views.Demo1APIView.as_view()),

path('auth2/', views.Demo2APIView.as_view()),#自定义权限

path('auth3/', views.Demo3APIView.as_view()),#限流

path('auth4/', views.Demo4APIView.as_view()),#过滤

path('data5/', views.Demo5APIView.as_view()),#排序

path('data6/', views.Demo6APIView.as_view()),#分页

path('data7/', views.Demo7APIView.as_view()),

]

views视图文件

from django.shortcuts importrender#Create your views here.

from rest_framework.views importAPIViewfrom rest_framework.response importResponsefrom rest_framework.permissions importIsAuthenticated, IsAdminUser#用户的认证和权限识别

classDemo1APIView(APIView):#只允许登录后的用户访问

permission_classes =[IsAuthenticated]defget(self, request):#个人中心

return Response("个人中心")classDemo2APIView(APIView):#只允许管理员访问

permission_classes =[IsAdminUser]defget(self, request):#个人中心2

return Response("个人中心2")#自定义权限

from rest_framework.permissions importBasePermissionclassMyPermission(BasePermission):defhas_permission(self, request, view):"""针对访问视图进行权限判断,必须使用xiaoming用户

:param request: 本次操作的http请求对象

:param view: 本次访问路由对应的视图对象

:return:"""

if request.user.username == "xiaoming":returnTruereturnFalseclassDemo3APIView(APIView):

permission_classes=[MyPermission]defget(self, request):"""个人中心3"""

return Response("个人中心3")#限流

from rest_framework.throttling importUserRateThrottle, AnonRateThrottleclassDemo4APIView(APIView):

throttle_classes= [UserRateThrottle, AnonRateThrottle] #全局配置后,这里就不用指定

defget(self, request):"""投票页面"""

return Response("投票页面")#过滤

from rest_framework.generics importGenericAPIView, ListAPIViewfrom students.models importStudentfrom opt.serializers importStudentModelSerializerfrom django_filters.rest_framework importDjangoFilterBackend#'django_filters.rest_framework.DjangoFilterBackend'

classDemo5APIView(ListAPIView):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer

filter_backends= [DjangoFilterBackend] #全局配置后,这里就不用指定了。

filter_fields = ['age', "id"] #声明过滤字段

#排序

from rest_framework.filters importOrderingFilterclassDemo6APIView(ListAPIView):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer

filter_backends= [DjangoFilterBackend, OrderingFilter] #局部配置会覆盖全局配置

filter_fields = ['id', "sex"]

ordering_fields= ['id', "age"]#分页

from rest_framework.pagination importPageNumberPagination, LimitOffsetPagination"""1. 自定义分页器,定制分页的相关配置"""

"""# 页码分页 PageNumberPagination

前端访问形式:GET http://127.0.0.1:8000/opt/data7/?page=4

page=1 limit 0,10

page=2 limit 10,20

# 偏移量分页 LimitOffsetPagination

前端访问形式:GET http://127.0.0.1:8000/opt/data7/?start=4&size=3

start=0 limit 0,10

start=10 limit 10,10

start=20 limit 20,10"""

classStandardPageNumberPagination(PageNumberPagination):"""分页相关配置"""page_query_param= "page" #设置分页页码关键字名

page_size = 3 #设置每页显示数据条数

page_size_query_param = "size" #设置指定每页大小的关键字名

max_page_size = 5 #设置每页显示最大值

classStandardLimitOffsetPagination(LimitOffsetPagination):

default_limit= 2 #默认限制,默认值与PAGE_SIZE设置一致

limit_query_param = "size" #limit参数名

offset_query_param = "start" #offset参数名

max_limit = 5 #最大limit限制

classDemo7APIView(ListAPIView):

queryset=Student.objects.all()

serializer_class=StudentModelSerializer#分页

#页码分页类

pagination_class =StandardPageNumberPagination#偏移量分页类

#pagination_class = StandardLimitOffsetPagination

但是只显示五个,是在代码设置最大显示5个,当设置显示8个时,不会生效,只会显示5个

java中fitlter,068.Python框架Django之DRF视图集使用相关推荐

  1. python drf_067.Python框架Django之DRF视图类

    一 关于视图类的一下概念 drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. ...

  2. mysql 中的neq_mysql中neq使用Python的Django框架中的压缩组件Django Compressor_MySQL

    为了加快网站的加载速度,我们通常要多js和css进行压缩处理.这些js和css的压缩工作如果都手动处理,费时费力. <mysql中neq使用Python的Django框架中的压缩组件Django ...

  3. Java中常见的日志框架

    可能是太过于常见了,所以使得大家很少关注,只是要用到的时候复制粘贴一份就行,甚至连日志配置文件中的配置语法都不清楚.另外一方面,Java中提供的日志组件太多了,一会儿log4j,一会儿logback, ...

  4. java 中的fork join框架

    文章目录 ForkJoinPool ForkJoinWorkerThread ForkJoinTask 在ForkJoinPool中提交Task java 中的fork join框架 fork joi ...

  5. python框架django文档_Django基础——Django框架介绍及模板语言

    Django框架,我们只需要关心二点: 1.根据用户访问不同的路径执行不同的函数 2.从HTML读取出内容,并且完成字符串的替换 而socket通信不需要我们自己写: 新建Django项目 命令行创建 ...

  6. Python框架Django快速入门

    原文地址:https://simpleisbetterthancomplex.com/series/2017/09/04/a-complete-beginners-guide-to-django-pa ...

  7. python框架django入门_web框架之Django(python3入门)

    -ORM ORM是什么? 不是django独有或者python独有的 对象关系映射 python中主流的几个ORM框架 django的orm(django已经封装好了,必须在django中使用) sq ...

  8. python框架django的使用_Django框架的基本使用,若依框架

    Django框架的基本使用,若依框架 Django框架的基本使用 Django是一个功能强大的web框架 框架模式 1.MVC和MTV框架 MVC:Web服务器开发领域里著名的MVC模式,所谓MVC就 ...

  9. 使用python框架Django搭建web应用

    一.Django简介 1. web框架介绍 具体介绍Django之前,必须先介绍Web框架的概念. Web框架: 别人已经设定好的一个Web网站模板,你学习它的规则,然后"填空"或 ...

最新文章

  1. 游戏控制杆OUYA游戏开发快速入门教程
  2. HDU-3177 Crixalis's Equipment 贪心
  3. php编程习惯,经验分享:PHP编程的5个良好习惯(二)
  4. Spring(1)-IOC
  5. C语言骚操作:结构体初始化方法
  6. 如何在SQL Server中检查日期是否为假期
  7. Selenium自动化测试WebDriver下载
  8. 一起谈.NET技术,用NuGet掌管你的Visual Studio扩展
  9. 【FlexSim2019】自学笔记:交通工具路径设置 | NetworkNode | 操作员固定路径 | 叉车固定路径
  10. ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.33.10' (111) 解决方法
  11. 第7章 XSL高级应用
  12. [AD19] 使用元器件向导为元件绘制PCB封装
  13. 计算机基础高一知识点,计算机基础全部知识点_.doc
  14. IDEA中快捷输入法
  15. C语言/C++基础之五彩炫酷珠
  16. UML相关工具一览(2018年5月更新)
  17. Lambda表达式到底是什么?——简单了解Lambda表达式
  18. 《Spring揭秘》读书笔记 3:Spring MVC
  19. centos8调整分辨率
  20. 线程经典实例——吃苹果问题

热门文章

  1. GitOps—通过CI/CD自动化构建虚拟机模版
  2. 哈希函数(Hash Functions - 散列函数)的基本介绍(SHA-2,SHA-256,MD-5,Scrypt,BCrypt等)
  3. Docker在linux下的安装
  4. 几个简单的Linux驱动程序
  5. ppt倒计时3分钟_这些出神入化的PPT小技巧,帮你轻松告别丑PPT!花3分钟看一看吧...
  6. ftp可以传输什么类型文件_为什么文件传输软件总让数据“没有安全感”?
  7. sudo修改文件夹名字_【转载】MAC系统修改帐号短名和个人文件夹名称
  8. android studio防止反编译,防反编译利器-Android studio混淆代码压缩apk包体积
  9. linux修改文件权限的命令_Linux基础文件权限管理
  10. java撤销上一步_CAD快速入门技巧:CAD软件中撤销操作的方法汇总