Python正课141 —— DRF 进阶2 请求、响应与视图

python

https://www.cnblogs.com/xuexianqi/p/13267845.html

1.请求

# 请求对象

# from rest_framework.request import Request

def __init__(self, request, parsers=None, authenticators=None,

negotiator=None, parser_context=None):

# 二次封装request,将原生request作为drf request对象的 _request 属性

self._request = request

def __getattr__(self,item):

return getattr(self._request,item)

# 请求对象.data:前端以三种编码方式传入的数据,都可以取出来

# 请求对象..query_params 与Django标准的request.GET相同,只是更换了更正确的名称而已。

2.响应

#from rest_framework.response import Response

def __init__(self, data=None, status=None,

template_name=None, headers=None,

exception=False, content_type=None):

#data:你要返回的数据,字典

#status:返回的状态码,默认是200,

-from rest_framework import status在这个路径下,它把所有使用到的状态码都定义成了常量

#template_name 渲染的模板名字(自定制模板),不需要了解

#headers:响应头,可以往响应头放东西,就是一个字典

#content_type:响应的编码格式,application/json和text/html;

# 浏览器响应成浏览器的格式,postman响应成json格式,通过配置实现的(默认配置)

#不管是postman还是浏览器,都返回json格式数据

# drf有默认的配置文件---》先从项目的setting中找,找不到,采用默认的

# drf的配置信息,先从自己类中找--》项目的setting中找---》默认的找

-局部使用:对某个视图类有效

-在视图类中写如下

from rest_framework.renderers import JSONRenderer

renderer_classes=[JSONRenderer,]

-全局使用:全局的视图类,所有请求,都有效

-在setting.py中加入如下

REST_FRAMEWORK = {

'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类

'rest_framework.renderers.JSONRenderer', # json渲染器

'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器

)

}

二:视图

# 两个视图基类

APIView

GenericAPIView

1.基于APIView写接口

#### views.py

from rest_framework.generics import GenericAPIView

from app01.models import Book

from app01.ser import BookSerializer

# 基于APIView写的

class BookView(APIView):

def get(self,request):

book_list=Book.objects.all()

book_ser=BookSerializer(book_list,many=True)

return Response(book_ser.data)

def post(self,request):

book_ser = BookSerializer(data=request.data)

if book_ser.is_valid():

book_ser.save()

return Response(book_ser.data)

else:

return Response({'status':101,'msg':'校验失败'})

class BookDetailView(APIView):

def get(self, request,pk):

book = Book.objects.all().filter(pk=pk).first()

book_ser = BookSerializer(book)

return Response(book_ser.data)

def put(self, request,pk):

book = Book.objects.all().filter(pk=pk).first()

book_ser = BookSerializer(instance=book,data=request.data)

if book_ser.is_valid():

book_ser.save()

return Response(book_ser.data)

else:

return Response({'status': 101, 'msg': '校验失败'})

def delete(self,request,pk):

ret=Book.objects.filter(pk=pk).delete()

return Response({'status': 100, 'msg': '删除成功'})

#models.py

class Book(models.Model):

name=models.CharField(max_length=32)

price=models.DecimalField(max_digits=5,decimal_places=2)

publish=models.CharField(max_length=32)

#ser.py

class BookSerializer(serializers.ModelSerializer):

class Meta:

model=Book

fields='__all__'

# urls.py

path('books/', views.BookView.as_view()),

re_path('books/(?P<pk>\d+)', views.BookDetailView.as_view()),

2.基于GenericAPIView写的接口

# views.py

class Book2View(GenericAPIView):

#queryset要传queryset对象,查询了所有的图书

# serializer_class使用哪个序列化类来序列化这堆数据

queryset=Book.objects

# queryset=Book.objects.all()

serializer_class = BookSerializer

def get(self,request):

book_list=self.get_queryset()

book_ser=self.get_serializer(book_list,many=True)

return Response(book_ser.data)

def post(self,request):

book_ser = self.get_serializer(data=request.data)

if book_ser.is_valid():

book_ser.save()

return Response(book_ser.data)

else:

return Response({'status':101,'msg':'校验失败'})

class Book2DetailView(GenericAPIView):

queryset = Book.objects

serializer_class = BookSerializer

def get(self, request,pk):

book = self.get_object()

book_ser = self.get_serializer(book)

return Response(book_ser.data)

def put(self, request,pk):

book = self.get_object()

book_ser = self.get_serializer(instance=book,data=request.data)

if book_ser.is_valid():

book_ser.save()

return Response(book_ser.data)

else:

return Response({'status': 101, 'msg': '校验失败'})

def delete(self,request,pk):

ret=self.get_object().delete()

return Response({'status': 100, 'msg': '删除成功'})

#url.py

# 使用GenericAPIView重写的

path('books2/', views.Book2View.as_view()),

re_path('books2/(?P<pk>\d+)', views.Book2DetailView.as_view()),

3.基于GenericAPIView和5个视图扩展类写的接口

from rest_framework.mixins import  ListModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin

# views.py

class Book3View(GenericAPIView,ListModelMixin,CreateModelMixin):

queryset=Book.objects

serializer_class = BookSerializer

def get(self,request):

return self.list(request)

def post(self,request):

return self.create(request)

class Book3DetailView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):

queryset = Book.objects

serializer_class = BookSerializer

def get(self, request,pk):

return self.retrieve(request,pk)

def put(self, request,pk):

return self.update(request,pk)

def delete(self,request,pk):

return self.destroy(request,pk)

# urls.py

# 使用GenericAPIView+5 个视图扩展类 重写的

path('books3/', views.Book3View.as_view()),

re_path('books3/(?P<pk>\d+)', views.Book3DetailView.as_view()),

4.使用ModelViewSet编写5个接口

# views.py

from rest_framework.viewsets import ModelViewSet

class Book5View(ModelViewSet): #5个接口都有,但是路由有点问题

queryset = Book.objects

serializer_class = BookSerializer

# urls.py

# 使用ModelViewSet编写5个接口

path('books5/', views.Book5View.as_view(actions={'get':'list','post':'create'})), #当路径匹配,又是get请求,会执行Book5View的list方法

re_path('books5/(?P<pk>\d+)', views.Book5View.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),

5.源码分析ViewSetMixin

# 重写了as_view

# 核心代码(所以路由中只要配置了对应关系,比如{'get':'list'}),当get请求来,就会执行list方法

for method, action in actions.items():

#method:get

# action:list

handler = getattr(self, action)

#执行完上一句,handler就变成了list的内存地址

setattr(self, method, handler)

#执行完上一句 对象.get=list

#for循环执行完毕 对象.get:对着list 对象.post:对着create

6.继承ViewSetMixin的视图类

# views.py

from rest_framework.viewsets import ViewSetMixin

class Book6View(ViewSetMixin,APIView): #一定要放在APIVIew前

def get_all_book(self,request):

print("xxxx")

book_list = Book.objects.all()

book_ser = BookSerializer(book_list, many=True)

return Response(book_ser.data)

# urls.py

#继承ViewSetMixin的视图类,路由可以改写成这样

path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),

三:补充

在pycharm中查看类的继承关系

以上是 Python正课141 —— DRF 进阶2 请求、响应与视图 的全部内容, 来源链接: utcz.com/z/387633.html

回到顶部