一、Django的View和Django rest framework的APIView
1.View
Django中的View是所有基于类的view的父类,它负责将视图连接到URL、HTTP 方法调度(GET,POST等)和其它简单的功能。
2.APIView
APIView是drf中所有view的父类,本身继承于Django的VIew,只有简单的调度方法和健壮检查。
和View的不同请求和返回使用的drf的Request Response而不是django的HttpRequest HttpResponse。请求传入时进行身份验证,并在传给处理方法前进行权限检验。
任何APIException都会被捕捉并放入合适的想要中。
3.使用
3.1Django 项目搭建

3.2数据模型model.py
首先在models.py添加如下代码:
from django.db import models
# Create your models here.
class Author(models.Model):
name = models.CharField(max_length=50, verbose_name='姓名')
age = models.IntegerField(verbose_name='年龄')
sex = models.BooleanField(max_length=1, choices=((0, '女'), (1, '男')), verbose_name='性别', default=1)
birthday = models.DateField(auto_created=True, verbose_name='出生日期')
address = models.CharField(verbose_name='地址', max_length=200)
email = models.EmailField(verbose_name='邮箱')
def __str__(self):
return self.name
class Meta:
verbose_name = '作者'
verbose_name_plural = verbose_name
class Publisher(models.Model):
name = models.CharField(max_length=50, verbose_name='名字')
address = models.CharField(max_length=120, verbose_name='地址')
website = models.URLField(verbose_name='网址')
def __str__(self):
return self.name
class Meta:
verbose_name = '出版社'
verbose_name_plural = verbose_name
class Book(models.Model):
title = models.CharField(max_length=120, verbose_name='书名')
author = models.ManyToManyField(Author, verbose_name='作者')
publisher = models.ForeignKey(Publisher, verbose_name='出版社', related_name='book_publisher', on_delete=models.DO_NOTHING)
publication_date = models.DateField(verbose_name='出版日期')
def __str__(self):
return self.title
class Meta:
verbose_name = '书籍'
verbose_name_plural = verbose_name
3.3序列化
在bookApp下新建serializers.py,对模型进行序列化操作
from rest_framework import serializers
from bookApp.models import Book, Author, Publisher
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ('name', 'address', 'email')
class PublisherSerializer(serializers.ModelSerializer):
class Meta:
model = Publisher
fields = ('name', 'address', 'website')
class BookSerializer(serializers.ModelSerializer):
author = AuthorSerializer(many=True)
publisher = PublisherSerializer()
class Meta:
model = Book
fields = (
"title", "author", "publisher", "publication_date"
)
某字段结果可能有多条时,记得加many=True!否则无法正确显示。
3.4编写视图views.py,实现出版社的增删改查
因为一本书可以有多个作者,所以要加many=True
from django.shortcuts import render
from rest_framework.views import APIView
from .models import Book, Author, Publisher
from .serializers import BookSerializer, AuthorSerializer, PublisherSerializer
from rest_framework.response import Response
# Create your views here.
class BookListsViews(APIView):
def get(self, request):
books = Book.objects.all()
books_list = BookSerializer(books, many=True)
return Response(books_list.data)
class AuthorListsViews(APIView):
def get(self, request):
authors = Author.objects.all()
author_list = AuthorSerializer(authors, many=True)
return Response(author_list.data)
class PublisherListView(APIView):
def get(self, request):
publisher = Publisher.objects.all()
publisher_list = PublisherSerializer(publisher, many=True)
return Response(publisher_list.data)
def post(self, request):
data = request.data
serializer = PublisherSerializer(data=data)
serializer.is_valid()
serializer.save()
return Response(serializer.data)
def put(self, request, pk):
data = request.data
publisher = Publisher.objects.get(id=pk)
serializer = PublisherSerializer(publisher, data)
serializer.is_valid()
serializer.save()
return Response(serializer.data)
def delete(self, request, pk):
publisher = Publisher.objects.get(id=pk)
serializer = PublisherSerializer(data=Publisher)
serializer.is_valid()
publisher.delete()
return Response(serializer.data)
3.5配置urls.py
在bookApp下新建url.py
from django.urls import path, re_path
from .views import BookListsViews, AuthorListsViews, PublisherListView
urlpatterns = [
path('book/list/', BookListsViews.as_view()),
path('author/list/', AuthorListsViews.as_view()),
path('publisher/list/', PublisherListView.as_view()),
path('publisher/add/', PublisherListView.as_view()),
re_path('publisher/update/(?P<pk>[0-9])/', PublisherListView.as_view()),
re_path('publisher/delete/(?P<pk>[0-9])/', PublisherListView.as_view())
]
修改urls.py
"""DjangoDemo URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from bookApp import url as books_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(books_urls))
]
启动项目后在浏览器访问:
http://127.0.0.1:8000/api/book/booklist/

二、GenericAPIView
作用: 通常结合一个或多个Mixin扩展类使用,用来快速地实现列表视图或详情视图,即标准的增删改查功能。
与APIView的不同点:主要增加了 操作序列化器 和 数据库查询的属性或方法,为Mixin扩展类的执行提供支持
1.属性:serializer_class 指明视图使用的序列化器
方法:get_serializer_class()返回序列化器类,默认返回serializer_class
方法:get_serializer()返回序列化器对象,主要用来提供给Mixin扩展类使用,如果我们在视图中想要获取序列化器对象,也可以直接调用此方法
2.属性:queryset 指明使用的数据查询集
方法:get_queryset()返回视图使用的查询集,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回queryset属性,可以重写。
方法:get_object()
返回详情视图所需的模型类数据对象,主要用来提供给Mixin扩展类使用。
在试图中可以调用该方法获取详情信息的模型类对象。
若详情访问的模型类对象不存在,会返回404。
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。
3.属性:lookup_field 查找单个model实例时的字段,默认为pk(主键)
4.属性:pagination_class:分页
5.属性:filter_backend
6.属性:lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同
示例代码:GenericAPIView实现出版商实现增删改查
from django.shortcuts import render
from rest_framework.generics import GenericAPIView
from .models import Publisher
from .serializers import PublisherSerializer
from rest_framework.response import Response
# Create your views here.
class PublisherListView(GenericAPIView):
lookup_field = 'pk'
serializer_class = PublisherSerializer
queryset = Publisher.objects.all()
def get(self, request):
publisher = self.get_queryset()
publisher_list = self.get_serializer(publisher, many=True)
return Response(publisher_list.data)
def post(self, request):
data = request.data
serializer = self.get_serializer(data=data)
serializer.is_valid()
serializer.save()
return Response(serializer.data)
def put(self, request, pk):
data = request.data
publisher = self.get_object() # Publisher.objects.get(id=pk)
serializer = self.get_serializer(publisher, data)
serializer.is_valid()
serializer.save()
return Response(serializer.data)
def delete(self, request, pk):
publisher = self.get_object() # Publisher.objects.get(id=pk)
serializer = self.get_serializer(data=Publisher)
serializer.is_valid()
publisher.delete()
return Response(serializer.data)
三、总结
APIView和GenericAPIvIEW两个类的关系如下:

网友评论