【Django】---Django-restframework

Django的CBV
dfr基于CBV比纯粹的CBV功能更加强大,继承于django.views中的View
在路由的最后一定要添加/否则会重定向到get请求中。
源码都是基于以下的所以先看
继承类中的函数反射

class Animal(object):
	def __init__(self, name, age, func_str):
	self.name = name
	self.age = age
	func = getsttr(self,'sleep')  ==>self.sleep()
	func()
class Dog(Animal):
	def wangwang(self):
		print("汪汪叫")
	def sleep(self):
		print("睡觉")
alex = Dog("alex", 35, 'sleep')  #指定调用sleep函数 

as_views()源码,调用的本质还是返回一个view
在这里插入图片描述
只保留关键代码:

 @classonlymethod     #只允许类方法
    def as_view(cls, **initkwargs):   #cls:当前调用的类
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)   #实例化当前类
            return self.dispatch(request, *args, **kwargs)   #dispatch分发路由,来一个处理一个
        return view     #返回视图
    def dispatch(self, request, *args, **kwargs):
    ''' 此处的getattr与上面继承的那个例子中的getsttr用法类似
    	self:当前的类
    	request.method.lower():当前请求的方法将其转换为小写,请求的方法就是那几个GET POST PUT...
    '''
            handler = getattr( self, request.method.lower()) 
        return handler(request, *args, **kwargs)   #将结果返回,此时就能和view一样接收到请求了

一旦用户访问book,比如用get请求访问/book/
get请求访问=>view() =>return self.dispatch() =>return get()

一、APIview完成增删改查

APIview是DRF的核心,相较于View添加了什么呢?
在这里插入图片描述
剩下的部分和cbv中的介绍是相同的
留下重要部分:
1.重写了as_view方法
2.APIView重新构建了request请求,这个请求发过来的数据均为JSON!!!(重要)
获取原生的reques为request._request

@classonlymethod     #只允许类方法
class APIView:
    def as_view(cls, ):   #cls:当前调用的类
    	view = super().as_view()
    	return view
 class View:
 	def as_view(cls):
        def view(request,:
            self = cls(**initkwargs)   #实例化当前类
            return self.dispatch(request, *args, **kwargs)   #dispatch分发路由,来一个处理一个
        return view     #返回视图
    def dispatch(self, request, *args, **kwargs):
  '''1.APIView中和View不一样之处则是它重新构建了新的request对象
	 2.初始化:认证、权限、限流组件三件套
'''
		request = self.initialize_request(request, *args, **kwargs)
        self.request = request
		self.initial(request,*args,**kwargs)
        handler = getattr( self, request.method.lower()) 
        return handler(request, *args, **kwargs)   #将结果返回,此时就能和view一样接收到请求了```

最重要之一序列化器-Serializer

序列化:将数据库的数据输出
反序列化:将数据存入数据库

流程

1.设计Model
class Book(models.Model):
    title = models.CharField(max_length=32,verbose_name='书籍名称')
    price = models.IntegerField(verbose_name='价格')
2.针对模型设计序列化器
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=3)
    price = serializers.IntegerField()
3.做相应操作

对单条和全部数据做操作时需要区分开来
1)get获取全部的数据,参数:instance(需要序列化的对象)many(是否序列化全部数据)

 def get(self, request):   #序列化操作
        book_list = Book.objects.all()
        serializer = BookSerializers(instance=book_list,many=True)
        print(serializer.data)
        return HttpResponse(serializer.data)
2)post传入单条数
  def post(self,request):   #反序列化操作
          print('data',request.data)
          serializer = BookSerializers(data=request.data)
          #校验数据   首先校验字段是否存在,字段是否为所设定的数据类型,是否符合所设定的长度
          if serializer.is_valid():  #符合规则的数据都会放入到clearn数据中返回布尔值,只有所有字段都通过校验才返回True
             new_book = Book.objects.create(**serializer.validated_data)
             return Response(serializer.data)
          else:
              return Response(serializer.errors)   #返回错误信息

增查 (改删查(单条))针对单条的操作需要在url定义时区分开来
例如:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
update和create的区别则是是否传入instance,当为update方法时则传入经过校验的validated_data数据
直接用ModelSerializer实现序列化可以实现两项功能
1.字段的序列化
2.数据的改和查,写的逻辑更加的详细,能够完成多对一、多对多的逻辑。

二、GenericaAPI 实现增删改查

通用视图类,继承自APIView,主要增加了操作序列化器数据库查询的方法,作用时为下面Mixin扩展类的执行提供属性和方法,具体有:
(1)get_serializer_class(self) 获取序列化的类
(2)get_serializer(self,args,*kwargs)获取序列化对象
(3)get_queryset(self) 返回视图的查询集
(4)get_object(self) 返回详细视图所需的模型类数据对象

from rest_framework.generics import GenericAPIView

class PublishSerializers(serializers.ModelSerializer):
    class Meta:
        model = Publish
        fields = '__all__'

class PublishView(GenericAPIView):
    queryset = Publish.objects.all()  # 固定的获取所有的queryset
    serializer_class = PublishSerializers  # 指定固定的序列化器
    def get(self, request):
        serializer = self.get_serializer(instance=self.get_queryset(), many=True)  # 拿到的就是序列化对象
        return Response(serializer.data)

(感觉只是一个get还没能非常体现出它的简洁性)可能是自己没悟透
往后的查询就只需要更改模型和序列化器这两个变量就可以了(悟了悟了)
来对比一下APIView和GenericAPI在针对不同的模型做相同操作时需要变动的地方:
APIView每一个操作逻辑中的模型类和序列化器都需要修改
在这里插入图片描述
GenericAPI只需要修改最初始的queryset和serializer_class字段,后续的操作逻辑中均不用修改。
在这里插入图片描述
哇啊哇,不学不知道,学了吓一跳,之前的序列化和现在学的对比代码量少了太多,一个查询功能的代码量相当于现在的查询和添加的代码量。真行!
在这里插入图片描述

1.查询单条

使用GenericAPIView查询单条的操作,需要注意匹配路由时的有名分组细节,意思就是在路由设置时需要设置关键字参数,传递给对应的视图函数。以下两种方式皆可
在这里插入图片描述
在这里插入图片描述

class PublishDetailView(GenericAPIView):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializers

    def get(self, request, pk):
        # book = Book.objects.get (pk=id)
        # serializer = BookSerializers(instance=book, many=False)
        serializer = self.get_serializer(instance=self.get_object(), many=False)
        return Response(serializer.data)

2.修改单条数据

    def put(self, request, pk):
        print('data:', request.data)
        serializer = self.get_serializer(instance=self.get_object(), data=request.data)  # 针对某个对象做修改
        if serializer.is_valid():
            serializer.save()  # 是创建还是更新的操作就判断是否有传入一个实例,传入实例则为更新
        else:
            return Response(serializer.errors)
        return Response()

对比一下最开始学的修改单条数据的方法,简直省事太多!
在这里插入图片描述

3.删除数据

 def delete(self, request, pk):
        self.get_object().delete()
        return Response('删除成功')

三、MixIn混合类

这个更简单!比昨天的又又又少了代码了,就是不知道这样的话对于数据的校验方便不,不过昨天可以重写数据校验返回数据
在这里插入图片描述
一页截图就完成了,返回的均为混合类所封装好的功能,这些功能就是在GenerialView缩写好的哪些逻辑,一下更新某条数据的源码。
在这里插入图片描述
接下来做数据验证。
在这里插入图片描述
要注意重写的名字需要是validate_想要验证的字段名,这样才可以验证成功否则就无法正常的进行验证。调用结果如下:
在这里插入图片描述

四、基于MixIn的再封装(直接两行完成)

在这里插入图片描述
真的有意思啊,django你是真的行。增删改查查就这么几行数据!可能在操作里面用不着做每次都会做这几样,可以自己灵活搭配!!
在这里插入图片描述
不能再封装了吧!课程都是看一个Bazinga老师讲的,我也不知道到底谁发布的才是正主XD,反正讲得真的太好了!!

五、ViewSet路由分发

不用在同时有两个get请求的时候多写两个类进行分别响应操作了,可以使用viewset自己会进行视图的分发。
路由的定义
在这里插入图片描述
在as_view({})中写好所绑定好的请求和功能之间的关系,当发起某一个请求的时候则会对应的响应。比如当发出单条的请求的时候只需要跟上pk值即可。
在这里插入图片描述
主要的分发逻辑为如下:
在这里插入图片描述
接受到的对象为:{‘get’:‘get_all’,‘post’:‘add_object’}
将action取出后使用getattr将其转变为handler可以调用的类型。将其传过去则名字和方法就一一对应可以调用了。
上面只是一个匹配路由的逻辑,当然一路走来那么多封装肯定不会让我们自己再写那么多的逻辑,直接就调用封装在MixIn类中的ListModelMixin、CreateModelMixin的那个五类,类里面就有增删改查的几个方法,如CreateModelMixin的详细如下所示:
在这里插入图片描述
有一个create,那么在路由匹配的时候就直接相互匹配就可以了。
在这里插入图片描述

在这里插入图片描述
这下全封装完了,这样封装对于大多数情况下都很方便,有些地方需要重写。

六、路由组件

这是最后一点了,将路由配置的地方也加简洁一下,这样可以不用每次都去输入它的五个方法。
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值