上文中基于原生方法实现API会很繁琐,且缺少数据验证功能,因此可以使用Django Rest Farmework快速实现API
1、DRF环境安装
1.1、安装DRF
$ pip install djangorestframework
1.2、项目中引入DRF功能
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # 引入DRF
'apps',
]
2、基于DRF实现查询API
基于DRF实现API需要一下基本步骤:
- 创建数据模型Model
- 创建序列化器Serializer
- 创建视图View
-
2.1、序列化
序列化分为序列化和反序列化
序列化就是将模型对象转换为字典,经过response后返回Json字符串
- 反序列化接收客户端发送的数据,完成数据校验后,把接收到的数据转换为模型
2.2、创建数据模型
from django.db import models
class ProjectHost(models.Model):
"""
主机信息模型
"""
ip = models.GenericIPAddressField(verbose_name='主机IP'),
project_name = models.CharField(max_length=64, verbose_name='项目名称'),
host_user = models.CharField(max_length=32, verbose_name='主机用户'),
number = models.IntegerField(default=1001, verbose_name='主机编号'),
status = models.BooleanField(default=True, verbose_name='主机状态')
description = models.TextField(verbose_name='描述')
class Meta:
db_table = 'app_hosts',
verbose_name = '主机信息表'
verbose_name_plural = verbose_name
# verbose_name: 在admin管理界面中显示中文时的名称,表示单数显示
# verbose_name_plural:表示中文复数显示
2.3、迁移模型至数据库
$ python manage.py makemigrations # 生成迁移文件
$ python manage.py migrate # 执行数据库迁移
2.4、定义序列化器
DRF中的Serializer使用类来定义,需继承自rest_farmework.serializer.Serializer
在apps应用下新建serializer.py
from rest_framework import serializers
class ProjectHostSerializer(serializers.Serializer):
"""主机信息序列化类"""
# 1、声明需要转换的字段类型
ip = serializers.CharField()
project_name = serializers.CharField()
host_user = serializers.CharField()
number = serializers.IntegerField()
status = serializers.BooleanField(default=True)
description = serializers.CharField()
序列化器声明后,不会自动调用,需要在视图中调用才可运行
序列化器无法直接接收数据,需要在视图中实例化后将数据集传递过来
2.5、创建视图View
使用序列化器的视图需要以下四个步骤
- 获取数据集
- 实例化序列化器,获取序列化对象
- 调用序列化器的data方法获取序列化后的数据
- 返回数据 ```python from django.views import View from django.http.response import JsonResponse from apps.models import ProjectHost from apps.serializer import ProjectHostSerializer
class ProjectHostView(View): def get(self, request):
# 1、获取数据集
host_list = ProjectHost.objects.all()
# 2、实例化序列化器,获取序列化对象,如果获取数据集为多个,则需要使用many指定多条
serializer = ProjectHostSerializer(instance=host_list, many=True)
# 3、调用序列化器的data方法获取序列化后的数据
data = serializer.data
# 4、返回数据
return JsonResponse(data=data, status=200, safe=False)
<a name="RE7By"></a>
#### 2.6、创建路由urls
<a name="mouGE"></a>
#### 2.4、创建路由
Django路由包含项目入口路由及应用路由,分别在项目目录和应用目录下
- 项目路由中引入应用路由drfdemo/urls.py
```python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include("apps.urls")), # 新增
]
- 应用路由下创建urs.py,添加视图路由 ```python from django.urls import path from apps.views import ProjectHostView # 引入视图方法
urlpatterns = [ path(‘projecthost/‘, ProjectHostView.as_view()), # 添加视图路由 ]
<a name="H4vX8"></a>
### 3、基于DRF实现新增更新API
新增数据时,则是接收客户端数据,经过序列化后写入数据库,因此为反序列化操作,新增API仅需要修改serializer.py和view.py
<a name="bta4m"></a>
#### 3.1、创建序列化器
```python
from rest_framework import serializers
from apps.models import ProjectHost
# 4、在字段中添加validators选项参数,进行补充验证
def val_projectname(value):
if "mall" in value.lower():
raise serializers.ValidationError(detail='项目组不能为mall', code="validate_host_user")
return value
class ProjectHostSerializer(serializers.Serializer):
"""主机信息序列化类"""
# 1、声明需要转换的字段类型
# 1.1、声明时也可以指定简单验证,方法(一)
id = serializers.IntegerField(read_only=True) # 只读字段,反序列时不会要求id字段
ip = serializers.CharField(required=True) # 必填字段
project_name = serializers.CharField(validators=[val_projectname]) # validators只能接收列表,且列表中只能为函数名
host_user = serializers.CharField(default='app') # 如果客户端没有提交,则默认值为app
number = serializers.IntegerField(max_value=1088, min_value=1001, error_messages={
"max_value": "最大值仅允许1088",
"min_value": "最小值仅允许1001"
}) # 指定允许提交数据范围
status = serializers.BooleanField(default=True)
description = serializers.CharField(allow_null=True, allow_blank=True) # 允许为空
# 2、对单个字段进行数据验证,方法(二)
def validate_host_user(self, value):
# 方法名必须以validate开头,会自动被is_valid调用
if "root" in value.lower():
raise serializers.ValidationError(detail='用户不能为root', code="validate_host_user")
return value
# 3、对多个字段进行数据验证,方法(三)
def validate(self, attrs):
# 验证来自客户端的所有数据,validate是固定方法名,attrs是序列化器实例化时传入的data选项数据
if "root" in attrs.get('host_user') and "oms" in attrs.get('project_name'):
raise serializers.ValidationError(detail='用户不能为root,且项目组不能为oms', code="validate")
return attrs
# 3、模型操作方法
def create(self, validated_data):
# 添加数据操作,方法名和参数均为固定
project_host = ProjectHost.objects.create(**validated_data)
return project_host
def update(self, instance, validated_data):
# 更新数据操作
for key, value in validated_data.items():
setattr(instance, key, value)
return instance
3.2、创建视图
import json
from django.views import View
from django.http.response import JsonResponse
from apps.models import ProjectHost
from apps.serializer import ProjectHostSerializer
class ProjectHostView(View):
def post(self, request):
# 1、接收客户端提交的新增数据
data = json.loads(request.body)
# 2、实例化序列化器,获取序列化对象
serializer = ProjectHostSerializer(data=data)
# 3、验证序列化数据
serializer.is_valid(raise_exception=True) # 验证失败抛出异常
# 数据入库
serializer.save() # save()方法,实例化序列化器时,传入instance则调用update方法,没有传入则调用create方法
# 4、返回数据
return JsonResponse(data=serializer.validated_data, status=200, safe=False)
def put(self, request, pk):
# 1、获取数据集
try:
project_host = ProjectHost.objects.get(pk=pk)
except ProjectHost.DoesNotExist:
return JsonResponse(data={}, status=404)
# 2、接收客户端提交的修改数据
data = json.loads(request.body)
# 3、实例化序列化器,获取序列化对象,传入instance对象后调用save()方法,则会调用update方法
serializer = ProjectHostSerializer(instance=project_host, data=data)
# 4、验证序列化数据
serializer.is_valid(raise_exception=True) # 验证失败抛出异常
# 5、数据入库
serializer.save() # save()方法,实例化序列化器时,传入instance则调用update方法,没有传入则调用create方法
# 6、返回数据
return JsonResponse(data=serializer.data, status=200, safe=False)
3.3、创建url
from django.urls import path, re_path
from apps.views import ProjectHostView
urlpatterns = [
path('projecthost/', ProjectHostView.as_view()),
re_path('projecthost/(?P<pk>\d+)', ProjectHostView.as_view()),
]
