今日内容概要
序列化与反序列化
def介绍和快速使用
cbv源码流程分析
drf之APIView和Request对象分析
内容详细
1、序列化和反序列化
最核心最常见的一个过程就是序列化
所谓序列化就是把数据转换格式,序列化可以分两个阶段
字典,列表,对象------》json/xml/prop,massagepack--->提供给别人(前端或其他服务)
我们在django中获取到的数据默认是模型对象(qs对象),但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人----》序列化过程
前端传入到后台的数据---》json格式字符串---》后端存到数据库中,需要转成python中的对象---》把json格式字符串转成python对象存到数据库的过程称为----》反序列化
2、drf介绍和快速使用
地址:127.0 .0 .1 :8080 /books
路由:path('/books' ,views.books)
视图函数中:通过orm查出所有图书(qs)--->序列化(for 循环自己拼成列表套字典[{name:西游记,price:99 },{name:红楼梦,price:99 }])---->JsonResponse返回给前端
pip3 install djangorestframework
注意:django版本最新 4. x 一般用升级到3. x 或者 2. x
drf的最新版本最低支持django 3. x以上---》出一个小问题---》装django 2. x---》当你pip3 install的时候,由于低于2.2 不支持最新的drf---》把你老版本的django卸载---》给你装上最新版---》原来写的django项目可能有问题,运行不了
django2.2 以下--->drf降版本
django3.x---->drf使用最新
Python (3.6 , 3.7 , 3.8 , 3.9 , 3.10 )
Django (2.2 , 3.0 , 3.1 , 3.2 , 4.0 )
2.1、快速使用
以后看到的所有接口都是这5 个的变形:
使用postman测试:
-查询所有---》get 请求->http://127.0 .0 .1 :8000 /books/
-查询一个---》get 请求->http://127.0 .0 .1 :8000 /books/2 /
-新增一个---》post 请求->http://127.0 .0 .1 :8000 /books/ body中带数据
-修改-----》put 请求:修改单个字段或者多个字段,patch 请求:只修改某个字段--->实际编码中,基本都用put
http://127.0 .0 .1 :8000 /books/1 / body体中传入修改的数据
-删除一个---》delete-->http://127.0 .0 .1 :8000 /books/1 /
视图 views.py
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .serializer import BookSerializer
class BookView (ModelViewSet ):
queryset = Book.objects.all ()
serializer_class = BookSerializer
路由 urls.py
from django.contrib import admin
from django.urls import path
from rest_framework.routers import SimpleRouter
from app01 import views
router = SimpleRouter()
router.register('books' , views.BookView, 'books' )
urlpatterns = [
path('admin/' , admin.site.urls),
]
urlpatterns += router.urls
序列化类 在app01下创建serializer.py文件
from .models import Book
from rest_framework import serializers
class BookSerializer (serializers.ModelSerializer):
class Meta :
model = Book
fields = '__all__'
模型 models.py
from django.db import models
class Book (models.Model):
name = models.CharField(max_length=32 )
price = models.DecimalField(decimal_places=2 , max_digits=5 )
author = models.CharField(max_length=32 )
3、cbv源码流程分析
path('test/' , views.TestView.as_view())
"""
第二个参数是函数内存地址 views.TestView.as_view()
as_view()执行完,也是一个内存地址>>>闭包函数view的内存地址
当请求来了,路由匹配成功
执行view(request) 传入当次请求的request对象
执行view(request) 本质上就是:
return self.dispatch(request, *args, **kwargs)
去View类中找 dispatch
如果是get请求就会执行视图类中的get方法
如果是post请求,就会执行视图类的post方法
"""
View类的方法--》@classonlymethod
handler = getattr (self, request.method.lower(), self.http_method_not_allowed)
return handler(request, *args, **kwargs)
"""
getattr反射
从当前对象(视图类的对象)---》如果是get请求--》会拿到get方法
handler就是get方法
handler(request)本质就是---》get(request)
"""
完成类似于property ,classmethod ...
4、drf之APIView和Request对象分析
from django.views.generic.base import View
from django.views.generic import View
from django.views import View
路由:path('order/' , views.OrderView.as_view())
第二个参数是函数内存地址
APIView的as_view的执行结果:
本质还是用了View类的as_view内的view闭包函数,去掉了csrf认证
当请求来了 触发view闭包函数执行,并且传入request 调用了 self.dispatch:
self是视图类的对象,从OrderView中找dispatch,但是找不到 父类APIView中有 本质上执行的dispatch是APIView
view = super ().as_view(**initkwargs)
return csrf_exempt(view)
def dispatch (self, request, *args, **kwargs ):
request = self.initialize_request(request, *args, **kwargs)
self.request = request
try :
self.initial(request, *args, **kwargs)
if request.method.lower() in self.http_method_names:
handler = getattr (self, request.method.lower(), self.http_method_not_allowed)
else :
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
1 包装了新的Request对象,以后视图类中的方法中传入的request对象都是新的
2 在进入视图函数之前,执行了三大认证
3 无论三大认证还是视图函数的方法,执行过程中出了异常,都会被处理掉
request = self.initialize_request(request, *args, **kwargs)
APIView的initialize_request 核心代码:
from rest_framework.request import Request
return Request(
request,
parsers=self.get_parsers(),
authenticators=self.get_authenticators(),
negotiator=self.get_content_negotiator(),
parser_context=parser_context
)
新的Request中:self._request = request
新的request._request是老的request
新的:<class 'rest_framework.request.Request' >
老的:<class 'django.core.handlers.wsgi.WSGIRequest' >
self.initial(request, *args, **kwargs)
APIView的核心代码:
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
view = super ().as_view(**initkwargs)
return csrf_exempt(view)
在视图函数上加装饰器 csrf_exempt装饰器 装饰器本质就是一个函数
@csrf_exempt
index=csrf_exempt(index)
def index (request )
pass
上面跟 csrf_exempt(index) 一毛一样
Request对象分析
前端post请求传入的数据 在老的request.POST请求下 老的只能处理urlencoded和formdata编码格式,json格式不能处理
无论前端用什么编码post提交的数据,都从data中获取
以后直接使用新的request.method request.path 拿到的就是老的 request.method...
对象.调用属性或方法会触发 魔法方法 __getattr__
原因在于新的request类重写了__getattr__, 以后新的request.method用的时候本质就是request._request.method
def __getattr__ (self, attr ):
try :
return getattr (self._request, attr)
except AttributeError:
return self.__getattribute__(attr)
新的request当老的用即可,只是多了个data前端post请求传入的数据,三种编码格式都可以
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY