2个视图类,5个视图扩展类,9个子类视图,视图集,action的使用,路由的使用

本文介绍了Django REST framework中APIView和GenericAPIView的使用,包括视图基类和扩展类的讲解,以及9个子类视图的示例。此外,还详细阐述了视图集、action的使用方法和路由配置的实践操作。
摘要由CSDN通过智能技术生成

一.昨日回顾

1 序列化类
	-写一个类继承Serializer或者ModelSerializer
	-写字段(很多字段类),很多字段属性
	-视图类中:实例化得到一个对象:
		-新增:data=字典
		-修改:instance,data
		-序列化:instance
	-对象
		-对象.data
		-对象.errors
		-对象.instance
2 source
	-修改序列化后字典的key(字段名和source对应的名不能一样)
	-执行函数(直接连表操作)
	-可以.连表操作
3 SerializerMehtodField
	-写在Serializer中
		publish=serializers.SerializerMethodField()
		def get_publish(self,obj):
	-它不可以被反序列化
		在Serializer中写两字段,一个作为序列化字段,一个作为反序列化字段

4 ModelSerializer(用的多)
	-写一个类
	-写一个内部类
	class Meta:
		model=表模型
		fields='__all__'
		fields-['id','name']
		exclude=()  #排除哪些字段
		read_only_field=[]
		extra_kwargs={'name':{'required':True}}
		depth=1
	-重写某些字段
		-直接以fields中的 某个字段为字段名,继续写即可
	-局部钩子,全局钩子
5 反序列化校验源码分析
6 many=True 源码分析
	-__new__和__init__和__call__
		-对象()触发该对象类的__call__
7 请求和响应
	-Request对象
		-data
		-__getattr__
	-Response对象
		-data
		-status
		-headers
	-通过配置实现前端只显示json格式
		-在setting中全局配置
		-在视图类中局部配
	-drf有一套默认的配置文件,自己配置需要在settings.py中
	REST_FRAMEWORK={}

二.今日内容

1. 2个视图类

①视图基类APIView

  1. 路径:rest_framework.views.APIView
  2. 继承==>原始View
  3. 重新封装成了drf的request对象
  4. 返回drf的Response对象

②通用视图类GenericAPIView

  1. 路径:rest_framework.generic.GenericAPIView
  2. 继承:APIView
  3. 主要属性:
    -queryset:需要查询的模型对象集
    -serializer_class:需要使用的序列化器类
# Django REST framework 提供的视图的主要作用:
	控制序列化器的执行(检验,保存,转换数据)
	控制数据库查询的执行
# APIView:继承了原生Django的View
# GenericAPIView:继承了APIView
	-queryset=models.Book.objects.all()
	-serializer_class=serializer.BookModelSerializer
	-get_queryset:获取配置的queryset
	-get_object:路由中的分组字段必须是pk
	-get_serializer:获取配置的序列化类

# 最终总结
# 两个基类
APIView:如果跟models没有关系(没有数据库相关操作),就继承它
GenericAPIView:有关数据库操作,queryset和serializer_class

代码演示

models.py
class Book(models.Model):
	id = models.AutoField(primary_key=True)
	title=models.CharField(max_length=32,null=True)
	price=models.DecimalField(max_digits=5,decimal_places=2,null=True)
	publish=models.CharField(max_length=32,null=True)

urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    # APIView
    path('books/',views.BookAPIView.as_view()),
    re_path('^books/(?P<pk>\d+)',views.BookDetailAPIView.as_view()),


    # GenericAPIView
    path('books_ger/', views.BookGenericAPIView.as_view()),
    re_path('^books_ger/(?P<pk>\d+)', views.BookDetailGenericAPIView.as_view()),

]
serializer.py
from app01 import models
from rest_framework import serializers

class BookModelSerializer(serializers.ModelSerializer):
	class Meta:
		model=models.Book
		fields='__all__'
views.py
from app01 import models,serializer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView

# 继承了APIView

class BookAPIView(APIView):
	def get(self,request):
		book_list=models.Book.objects.all()
		ser=serializer.BookModelSerializer(book_list,many=True)
		return Response(ser.data)
	def post(self,request):
		ser=serializer.BookModelSerializer(data=request.data)
		if ser.is_valid():
			ser.save()
		return Response('成功')

class BookDetailAPIView(APIView):
	def get(self,request,pk):
		book=models.Book.objects.get(id=pk)
		ser=serializer.BookModelSerializer(book)
		return Response(ser.data)

	def put(self,request,pk):
		book=models.Book.objects.get(id=pk)
		ser=serializer.BookModelSerializer(book,data=request.data)
		if ser.is_valid():
			ser.save()
		return Response('修改成功')

	def delete(self,request,pk):
		models.Book.objects.filter(id=pk).delete()
		return Response('删除成功')


# 继承了GenericAPIView

class BookGenericAPIView(GenericAPIView):

	queryset = models.Book.objects.all()
	serializer_class = serializer.BookModelSerializer
	def get(self,request):
		obj=self.get_queryset()
		ser=self.get_serializer(obj,many=True)
		return Response(ser.data)
	def post(self,request):
		ser=self.get_serializer(data=request.data)
		if ser.is_valid():
			ser.save()
		return Response('成功')

class BookDetailGenericAPIView(GenericAPIView):
	queryset = models.Book.objects.all()
	serializer_class = serializer.BookModelSerializer
	def get(self,request,*args,**kwargs):
		obj=self.get_object()
		ser=self.get_serializer(obj)
		return Response(ser.data)

	def put(self,request,*args,**kwargs):
		obj=self.get_object()
		ser=self.get_serializer(obj,data=request.data)
		if ser.is_valid():
			ser.save()
		return Response('修改成功')

	def delete(self,request,*args,**kwargs):
		self.queryset.filter(id=kwargs.get('pk')).delete()
		return Response('删除成功')

2. 5个视图扩展类

CreateModelMixin:create方法创建一条
DestroyModelMixin:destory方法删除一条
ListModelMixin:list方法获取所有
RetrieveModelMixin:retrieve获取一条
UpdateModelMixin:update修改一条

自定义的两个视图扩展类

# 自定义了两个视图扩展类
# class ListView():
#     def list(self,request, *args, **kwargs):
#         obj = self.get_queryset()
#         ser = self.get_serializer(obj, many=True)
#         return Response(ser.data)
#
# class CreateView():
#     def create(self,request, *args, **kwargs):
#         ser=self.get_serializer(data=request.data)
#         if ser.is_valid():
#             ser.save()
#         return Response('成功')
# class BookGenericView(GenericAPIView,CreateView,ListView):
#     queryset = models.Book.objects.all()
#     serializer_class = serializer.BookModelSerializer
#
#     def get(self, request, *args, **kwargs):
#         return self.list(request, *args, **kwargs)
#     def post(self, request, *args, **kwargs):
#         return self.create(request, *args, **kwargs)
#
#
#
# class BookDetailGenericAPIView(GenericAPIView):
#     queryset = models.Book.objects.all()
#     serializer_class = serializer.BookModelSerializer
#
#     def get(self, request, *args, **kwargs):
#         obj = self.get_object()
#         ser = self.get_serializer(obj)
#         return Response(ser.data)
#
#     def put(self, request, *args, **kwargs):
#         obj = self.get_object()
#         ser = self.get_serializer(obj, data=request.data)
#         if ser.is_valid():
#             ser.save()
#         return Response('修改成功')
#
#     def delete(self, request, *args, **kwargs):
#         self.queryset.filter(id=kwargs.get('pk')).delete()
#         return Response('删除成功')

drf提供的5个视图扩展类

### 使用drf提供的视图扩展类
##5个视图扩展类
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    UpdateModelMixin
# class BookGenericView(GenericAPIView,ListModelMixin,CreateModelMixin):
#     queryset = models.Book.objects.all()
#     serializer_class = serializer.BookModelSerializer
#
#     def get(self, request, *args, **kwargs):
#         return self.list(request, *args, **kwargs)
#     def post(self, request, *args, **kwargs):
#         return self.create(request, *args, **kwargs)
#
#
# class BookDetailGenericAPIView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
#     queryset = models.Book.objects.all()
#     serializer_class = serializer.BookModelSerializer
#
#     def get(self, request, *args, **kwargs):
#         return self.retrieve(request, *args, **kwargs)
#
#     def put(self, request, *args, **kwargs):
#         return self.update(request, *args, **kwargs)
#
#     def delete(self, request, *args, **kwargs):
#         return self.destroy(request, *args, **kwargs)

3. 9个子类视图

# 9个子类视图(rest_framework.generics)
CreateAPIView:继承CreateModelMixin,GenericAPIView,有post方法,新增数据
DestroyAPIView:继承DestoryModelMixin,GenericAPIView,有delete方法,删除数据
ListAPIView:继承ListModelMixin,GenericAPIView,有get方法获取所有
UpdateAPIView:继承UpdateModelMixin,GenericAPIView,有put和patch方法,修改数据
RetrieveAPIView:继承RetrieveModelMixin,GenericAPIView,有get方法,获取一条


ListCreateAPIView:继承ListModelMixin,CreateModelMixin,GenericAPIView,有get获取所有,post方法新增
RetrieveDestroyAPIView:继承RetrieveModelMixin,DestroyModelMixin,GenericAPIView,有get方法获取一条,delete方法删除
RetrieveUpdateAPIView:继承RetrieveModelMixin,UpdateModelMixin,GenericAPIView,有get获取一条,put,patch修改
RetrieveUpdateDestroyAPIView:继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView,有get获取一条,put,patch修改,delete删除

自定义的视图子类

# 自定义的视图子类
class CreateListGenericAPIView(GenericAPIView,CreateModelMixin,ListModelMixin):
	def get(self, request, *args, **kwargs):
		return self.list(request, *args, **kwargs)

	def post(self, request, *args, **kwargs):
		return self.create(request, *args, **kwargs)
class BookGenericAPIView(CreateListGenericAPIView):
	queryset = models.Book.objects.all()
	serializer_class = serializer.BookModelSerializer

drf提供的9个视图子类

#### 9个视图字类
# class CreateListGenericAPIView(GenericAPIView,CreateModelMixin,ListModelMixin):
#     def get(self,request,*args,**kwargs):
#         return self.list(request,*args,**kwargs)
#     def post(self,request,*args,**kwargs):
#         return  self.create(request,*args,**kwargs)
# from rest_framework.generics import CreateAPIView,ListAPIView,ListCreateAPIView
# from rest_framework.generics import UpdateAPIView,RetrieveAPIView,DestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView,RetrieveUpdateDestroyAPIView
#
# # class BookGenericView(CreateAPIView):
# # class BookGenericView(ListAPIView):
# class BookGenericView(ListCreateAPIView):
#     queryset = models.Book.objects.all()
#     serializer_class = serializer.BookModelSerializer
#
#
# # class BookDetailGenericAPIView(RetrieveAPIView):
# # class BookDetailGenericAPIView(RetrieveAPIView,UpdateAPIView):
# class BookDetailGenericAPIView(RetrieveUpdateDestroyAPIView):
#     queryset = models.Book.objects.all()
#     serializer_class = serializer.BookModelSerializer

4. 视图集

#视图集

# ViewSetMixin:重写了as_view 

# ViewSet:     继承ViewSetMixin和APIView
# GenericViewSet:继承ViewSetMixin, generics.GenericAPIView

# ModelViewSet:继承mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet
# ReadOnlyModelViewSet:继承mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet

代码演示

### urls.py
urlpatterns = [
    # path('admin/', admin.site.urls),
    
    # ## 使用视图集
    path('books_set/', views.BookSetView.as_view({'get':'list','post':'create'})),
    path('books_set/', views.BookSetView.as_view()), # 直接报错
    re_path('^books_set/(?P<pk>\d+)', views.BookSetView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
   
]
### views.py
# 视图集
# 继承一个东西,有5个接口
from rest_framework.viewsets import ModelViewSet
class BookSetView(ModelViewSet):
	queryset = models.Book.objects.all()
	serializer_class = serializer.BookModelSerializer



### ReadOnlyModelViewSet 只有查询接口
## urls.py
path('books_set/', views.BookSetView.as_view({'get':'list'})),
re_path('^books_set/(?P<pk>\d+)', views.BookSetView.as_view({'get':'retrieve'})),

## views.py
### 只有查询的接口
from rest_framework.viewsets import ReadOnlyModelViewSet
class BookSetView(ReadOnlyModelViewSet):
	queryset = models.Book.objects.all()
	serializer_class = serializer.BookModelSerializer

5. action的使用

# 只要继承了ViewSetMixin类
# 路由配置:path('books_mix/', views.BookView.as_view({'get':'lqz'}))
# 视图类的方法中就会有个action
class BookView(ViewSet):
    def lqz(self,request,*args,**kwargs):
        print(self.action)
        return Response('lqz')
    
    
# ViewSetMixin以后只要继承它,路由的配置就发生变化了,只需要写映射即可

代码演示

### urls.py
path('books_mix/', views.BookView.as_view({'get':'lqz'})),
path('books_mix2/', views.BookView.as_view({'get':'egon'})),

### views.py
### ViewSetMixin:视图类中的方法名,可以随便写,只需要映射对就可以
from rest_framework.viewsets import ViewSetMixin

# class BookView(ViewSetMixin,APIView):
class BookView(ViewSet):  # 可以直接写这个,代替上一条,因为ViewSet继承了ViewSetMixin,APIView
	def lqz(self,request,*args,**kwargs):
		print(self.action)
		return Response('lqz')
	def egon(self,request,*args,**kwargs):
		return Response('egon')

6. 路由的使用

# 自动生成路由
# SimpleRouter
# DefaultRouter

# 继承了ViewSetMixin的视图类,以后写路由,可以自动生成
from rest_framework import routers
# 实例化得到一个对象
router=router.SimpleRouter()
# 注册进路由
router.register('books',views.BookSetView)
# 把自动生成的路由配置到urlpatterns中
	-urlpatterns += router.urls
	-re_path(r'v1/',include(router.urls))

# 配置路由的方式
	-最原始的
		-path('books/',views.BookAPIView.as_view()),
	-ViewSetMixin的视图类
		-path('books_set/',views.BookSetView.as_view({'get':'list','post':'create'}))
	-ViewSetMixin的视图类
		-自动生成,上面讲的
# action
	-当自动生成路由的时候,由于视图类中还有其他方法,是无法自动生成路由的
	-加action装饰器:
		-methods:什么请求方式会触发被装饰函数的执行
		-detail:True是基于带id的路由生成的,如果是False,是基于不带id的路由生成的
		-@action(method=['get'],detail=True)

代码演示

### urls.py
from rest_framework import routers
# 实例化得到一个对象
router = routers.SimpleRouter()
# router = routers.DefaultRouter()
router.register('books', views.BookSetView, basename='book')
router.register('publish', views.PublishSetView, basename='publish')
print(router.urls) # 列表中放了很多路由
urlpatterns = [
    path('admin/', admin.site.urls),
   ...  
]
urlpatterns += router.urls

### views.py
from rest_framework.decorators import action
class BookSetView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer
    # path('', views.BookSetView.as_view({'get': 'login'}))
    # @action(methods=['get'], detail=False)
    @action(methods=['get'], detail=True)
    def login(self,request,*args,**kwargs):
        print(args)
        print(kwargs)
        print(self.action)
        return Response('登录成功')

    @action(methods=['post'], detail=False)
    def lqz(self,request,*args,**kwargs):
        return Response('lqz')

class PublishSetView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookModelSerializer
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值