1.APIView和View的不同
APIView
是REST framework提供的所有视图类的基类,继承自Django的View
父类。
APIView
与View
的不同之处在于:
-
传入到视图方法中的是REST framework的
Request
对象,而不是Django的HttpRequeset
对象; -
视图方法可以返回REST framework的
Response
对象,视图会为响应数据设置(renderer)符合前端期望要求的格式; -
任何
APIException
异常都会被捕获到,并且处理成合适格式的响应信息返回给客户端;django 的View中所有异常全部以HTML格式显示
drf的APIVIew或者APIView的子类会自动根据客户端的Accept进行错误信息的格式转换。
-
重新声明了一个新的as_view方法并在dispatch()进行路由分发前,会对请求的客户端进行身份认证、权限检查、流量控制。
APIView除了继承了View原有的属性方法意外,还新增了类属性:
-
authentication_classes 列表或元组,身份认证类
-
permissoin_classes 列表或元组,权限检查类
-
throttle_classes 列表或元祖,流量控制类
在APIView
中仍以常规的类视图定义方法来实现get() 、post() 或者其他请求方式的方法。
2.创建app并注册
在pycharm的Terminal端执行命令:创建app
python manage.py startapp stu_api_view
在项目的settings.py文件中注册app
INSTALLED_APPS = [
'stu_api_view',
]
3.模型序列化
在当前app下新建serializers.py文件,代码如下
from rest_framework import serializers
from stu_django.models import Student
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = "__all__"
extra_kwargs = {
"age": {
"max_value": 25,
"error_messages": {
"max_value": "年龄不能超过25岁!",
}
}
}
fields = "__all__":指定了要序列化的字段是所有字段,即将模型的所有字段都包含在序列化器中。
extra_kwargs:定义了一些额外的参数配置,这里针对 age 字段进行了配置。
max_value: 25:限制了 age 字段的最大值为 25。
error_messages:定义了当字段验证失败时的错误消息,这里指定了当 age 超过 25 岁时的错误消息为“年龄不能超过25岁!”。
当前所用到的model在app“stu_django”下代码如下:
from django.db import models
# Create your models here.
class Student(models.Model):
# verbose_name是在后台显示的名称
name = models.CharField(max_length=255, verbose_name="姓名")
sex = models.BooleanField(default=True, verbose_name="性别")
age = models.IntegerField(verbose_name="年龄")
classmate = models.CharField(db_column="class", max_length=5, verbose_name="班级编号")
description = models.TextField(max_length=1000, null=True, blank=True, verbose_name="个性签名")
class Meta:
# 表名
db_table = "student"
# 后台站点显示名称
verbose_name = "学生"
verbose_name_plural = verbose_name
# 将对象内容以字典的形式返回
def __str__(self):
return str(self.__dict__)
4.通过APIView实现的视图
from django.shortcuts import render
# Create your views here.
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from stu_django.models import Student
from .serializers import StudentModelSerializer
"""
GET /demo/students/ 获取所有学生信息
POST /demo/students/ 添加一个学生信息
GET /demo/students/<pk> 获取一个学生信息
PUT /demo/students/<pk> 更新一个学生信息
DELETE /demo/students/<pk> 删除一个学生信息
"""
# Create your views here.
class StudentAPIView(APIView):
def get(self,request):
"""获取所有学生信息"""
# 1. 从数据库中读取学生列表信息
student_list = Student.objects.all()
# 2. 实例化序列化器,获取序列化对象
serializer = StudentModelSerializer(instance=student_list, many=True)
# 3. 转换数据并返回给客户端
return Response(serializer.data)
def post(self,request):
"""添加一条数据"""
# 1. 获取客户端提交的数据,实例化序列化器,获取序列化对象
serializer = StudentModelSerializer(data=request.data)
# 2. 反序列化[验证数据、保存数据到数据库]
serializer.is_valid(raise_exception=True)
serializer.save()
# 3. 返回新增的模型数据给客户单
return Response(serializer.data, status=status.HTTP_201_CREATED)
class StudentInfoAPIView(APIView):
def get(self,request, pk):
"""获取一条数据"""
# 1. 使用pk作为条件获取模型对象
try:
student = Student.objects.get(pk=pk)
except Student.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
# 2. 序列化
serializer = StudentModelSerializer(instance=student)
# 3. 返回结果
return Response(serializer.data)
def put(self,request,pk):
"""更新数据"""
# 1. 使用pk作为条件获取模型对象
try:
student = Student.objects.get(pk=pk)
except Student.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
# 2. 获取客户端提交的数据
serializer = StudentModelSerializer(instance=student, data=request.data)
# 3. 反序列化[验证数据和数据保存]
serializer.is_valid(raise_exception=True)
serializer.save()
# 4. 返回结果
return Response(serializer.data, status=status.HTTP_201_CREATED)
def delete(self,request,pk):
"""删除数据"""
# 1. 根据PK值获取要删除的数据并删除
try:
Student.objects.get(pk=pk).delete()
except Student.DoesNotExist:
pass
# 2. 返回结果
return Response(status=status.HTTP_204_NO_CONTENT)
5.设置路由
设置子路由:在当前app下新建urls.py文件,设置的路由如下:
from django.urls import path, re_path
from . import views
urlpatterns = [
path("students/", views.StudentAPIView.as_view()),
re_path("^students/(?P<pk>\d+)/$", views.StudentInfoAPIView.as_view()),
]
^students/(?P\d+)/$ 匹配以 students/ 开头,后面跟着一个整数类型的参数,然后以 / 结尾的 URL。当请求的 URL 符合这个模式时,Django 就会提取其中的整数部分,并将其作为 pk 参数传递给 StudentInfoView 视图的相应方法(如 get、put、delete 方法)。
设置项目路由:在项目路由下设置总路由,如下所示。
from django.urls import path,include
urlpatterns = [
path("stu_api_view/", include("stu_api_view.urls")),
]
6.查看效果
执行命令启动项目, 访问地址:http://127.0.0.1:8000/stu_api_view/students/,能够正常访问就说明没有问题,如下图所示。
python manage.py runserver
7.操作
可以在上述启动页面直接操作增删改查或者通过调用外部接口进行操作。