一、 APIView是继承自CBV的view类,因此先说一下CBV。APIView重写了request请求,本来reqest.POST只能访问urlencode的参数,却无法访问json格式的数据。重新的request能够访问json数据。
#views类
#FBV
"""
面向过程的函数视图
"""
# def book(request):
# if request.method == "GET":
# return HttpResponse("GET请求...")
#
# else:
# return HttpResponse("POST请求...")
#路由部分
from django.urls import path
from app01 import views
urlpatterns = [
path('book/', views.BookView.as_view())
]
#CBV
from django.shortcuts import render, HttpResponse
from django.views import View
class BookView(View):
def get(self, request):
return HttpResponse("view get")
def post(self, request):
return HttpResponse("view post")
二、DRF框架
安装DRF
APIView是DRF框架的一个view函数,重写了request函数,解决了之前post不接受json的数据。
#路由不变,只是重写了request请求的方法
from rest_framework.views import APIView
class BookView(APIView):
def get(self, request):
print("query_params:", request.query_params)
return HttpResponse("view get")
def post(self, request):
print(request.data)
return HttpResponse("view post")
def delete(self, request):
return HttpResponse(request.query_params)
三、序列化以及进阶
1、serializers序列化使得程序的校验方面便捷并且前端数据好存取
#urls路由部分
from django.urls import path, re_path
from . import views
urlpatterns = [
path('author/', views.AuthorView.as_view()),
re_path(r'author/(\d+)', views.AuthorView.as_view())
]
#View部分
from rest_framework import serializers
from rest_framework.response import Response
# 针对模型设计序列化器
class BookSerializers(serializers.Serializer):
title = serializers.CharField(max_length=3)
price = serializers.IntegerField(required=False)
date = serializers.DateField(source="pub_date")
class BookView(APIView):
def get(self, request):
# 获取所有的书籍
book_list = Book.objects.all() # queryset[book01,book02,...]
# 构建序列化器对象:
serializer = BookSerializers(instance=book_list, many=True)
'''
temp = []
for obj in book_list:
d = {}
d["title"] = obj.title
d["price"] = obj.price
# d["pub_date"] = obj.pub_date
temp.append(d)
'''
return Response(serializer.data)
def post(self, request):
# 获取请求数据
print("data", request.data)
# 构建序列化器对象
serializer = BookSerializers(data=request.data)
# 校验数据
if serializer.is_valid(): # 返回一个布尔值,所有字段皆通过才返回True,serializer.validated_data serializer.errors
# 数据校验通过,将数据插入到数据库中
new_book = Book.objects.create(**serializer.validated_data)
serializer.instance = request.data
return Response(request.data)
else:
# 校验失败
return Response(serializer.errors)
def delete(self, request, id):
print(id)
author = Author.objects.get(pk=id).delete()
return Response(request.data)
# 修改数据
def put(self, request, id):
serializer = AuthorSerializers(data=request.data)
if serializer.is_valid():
Author.objects.filter(pk=id).update(**serializer.data)
return Response(request.data)
else:
return Response(serializer.errors)
重写序列化函数之create、update函数,分离模型和控制类的操作
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import serializers
from app01.models import Author
class AuthorSerializers(serializers.Serializer):
name = serializers.CharField(max_length=30)
company = serializers.CharField(max_length=40)
def create(self, request):
new_author = Author.objects.create(**self.validated_data)
self.instance = request.data
# 返回值必须是序列化数据
return self.instance
def update(self, instance, validated_data):
Author.objects.filter(pk=validated_data).update(**self.validated_data)
self.instance = instance
return instance
# Create your views here.
class AuthorView(APIView):
def get(self, request):
author_list = Author.objects.all()
# 序列化
serializer = AuthorSerializers(instance=author_list, many=True)
return Response(serializer.data)
def post(self, request):
# 反序列化
serializer = AuthorSerializers(data=request.data)
if serializer.is_valid():
new_instance = serializer.create(request)
return Response(new_instance)
else:
return Response(serializer.errors)
def delete(self, request, id):
author = Author.objects.get(pk=id).delete()
author_all = Author.objects.all()
return Response(request.data)
# 修改数据
def put(self, request, id):
serializer = AuthorSerializers(data=request.data)
if serializer.is_valid():
serializer.update(serializer.data, id)
return Response(serializer.instance)
else:
return Response(serializer.errors)
2、ModelSerializer自动帮忙补全序列化类的列验证
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import serializers
from app01.models import Author
class AuthorSerializers(serializers.ModelSerializer):
class Meta:
model = Author
# fields = "__all__"或者fields=["name","company"]
exclude = ["id"]
# Create your views here.
class AuthorView(APIView):
def get(self, request):
author_list = Author.objects.all()
# 序列化
serializer = AuthorSerializers(instance=author_list, many=True)
return Response(serializer.data)
def post(self, request):
# 反序列化
serializer = AuthorSerializers(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors)
def delete(self, request, id):
author = Author.objects.get(pk=id).delete()
author_all = Author.objects.all()
return Response(request.data)
# 修改数据
def put(self, request, id):
update_author = Author.objects.get(pk=id)
serializer = AuthorSerializers(instance=update_author, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors)
3、GenericAPIView继承了APIView类,使得序列化直接调用更加方便。多个view之间直接复制粘贴,修改两个参数即可复用。
from rest_framework.response import Response
from rest_framework import serializers
from app01.models import Author
from rest_framework.generics import GenericAPIView
class AuthorSerializers(serializers.ModelSerializer):
class Meta:
model = Author
# fields = "__all__"或者fields=["name","company"]
exclude = ["id"]
class AuthorView(GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializers
def get(self, request):
# author_list = self.get_queryset()获取查询结果集
# serializer = AuthorSerializers(instance=author_list, many=True)以上两个语句等价于
# serializer = AuthorSerializers(instance=self.get_queryset(), many=True)等价于
# self.get_serializer_class()获取类
serializer = self.get_serializer(instance=self.get_queryset(), many=True)
return Response(serializer.data)
def post(self, request):
# 反序列化
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors)
def delete(self, request, pk):
# 类似类.objects.get(pk=pk)
author = self.get_object().delete()
return Response(request.data)
# 修改数据
def put(self, request, pk):
serializer = self.get_serializer(instance=self.get_object(), data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors)
4、多继承,在GenericAPIView的基础上,封装了get,post等方法,由于请求链接不同,因此需要分成两个类
#路由部分
urlpatterns = [
path('author/', views.AuthorView.as_view()),
re_path("author/(?P\d+)", views.AuthorDetailView.as_view())
]
#views页面
from rest_framework import serializers
from app01.models import Author
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin
class AuthorSerializers(serializers.ModelSerializer):
class Meta:
model = Author
# fields = "__all__"或者fields=["name","company"]
exclude = ["id"]
class AuthorView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializers
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class AuthorDetailView(UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, GenericAPIView):
queryset = Author.objects.all()
serializer_class = AuthorSerializers
def get(self, request, pk):
return self.retrieve(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
# 修改数据
def put(self, request, pk):
return self.update(request, pk)
扩展:from rest_framework.generics import GenericAPIView, ListCreateAPIView,RetrieveUpdateDestroyAPIView
以上把多个方法集成封装到了一个类,调用起来会更加方便。
5、ViewSet重构了分发机制,可以重写设置方法名称
#路由分发
urlpatterns = [
path('author/', views.AuthorView.as_view({"get": "list"})),
re_path("author/(?P\d+)", views.AuthorView.as_view({"get": "get_object"}))
]
#view部分
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
class AuthorView(ViewSet):
queryset = Author.objects.all()
serializer_class = AuthorSerializers
def list(self, request):
return Response("get all")
def get_object(self, request, pk):
return Response("get"+pk)