Django - Rest Framework 框架
DRF 的安装与配置
为了简化API的开发过程,我们可以使用Django Rest Framework 框架实现API开发。使用框架开发不仅能减少代码冗余,还可以规范代码的编写格式,这对企业级开发来说很有必要,毕竟每个开发人员的编程风格存在一定的差异,开发规范可以方便其他开发人员查看和修改。
在使用Django Rest Framework 之前,首先安装 Django Rest Framework
pip install djangorestframework
安装完成之后进行配置:
# MyDjango\setting.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'index',
'user',
'rest_framework' # 添加 Django Rest Framework 框架
]
# Django Rest Framework 框架 设置信息
# 分页设置
REST_FRAMEWORK = {'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
# 每页显示多少数据
'PAGE_SIZE': 2}
案例以下面表讲解:
数据:
序列化类 Serializer
在项目的应用index 的 serializers.py 中定义序列化类:
class VocationSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
job = serializers.CharField(max_length=100)
title = serializers.CharField(max_length=100)
payment= serializers.CharField(max_length=100)
name = serializers.PrimaryKeyRelatedField(queryset=NAME_LIST)
def create(self, validated_data):
return Vocation.objects.create(**validated_data)
def update(self, instance, validated_data):
return instance.update(**validated_data)
自定义序列化类 VocationSerializer 的字段对应 模型Vocation 的字段,序列化字段的数据类型可以在 Rest Framework 的源码文件fields.py 中找到定义过程,它们都继承父类Field。
在定义序列化字段的时候,每个序列化字段允许设置参数信息,分析父类Field 的初始化参数,它们适用于所有序列化字段的参数设置,说明如下:
- read_only: 设置序列化字段的只读属性
- write_only:设置序列化字段的编辑属性
- required: 设置序列化字段的数据是否为空,默认值为True
- default: 设置序列化字段的默认值
- initial:设置序列化字段的初始值
- source:为序列化字段指定一个模型字段来源,如(email='user.email')
- allow_null:设置序列化字段是否为None ,若为True ,则序列化字段的值允许为None
自定义序列化类VocationSerializer 还定义了关系字段 name,重写了父类 BaseSerializer 的 create 和 update 函数。关系字段可以在源码文件relations.py 中找到定义过程。
定义路由:
# index\urls.py
urlpatterns = [
# path('<pk>/<age>.html', index.as_view(), name='index')
path('', vocationDef , name='myDef'),
path('vocationClass/', VocationClass.as_view(), name='vocationClass')
]
# index\views.py
from .models import Vocation
from .serializers import VocationSerializer
from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.views import APIView
@api_view(['GET', 'POST'])
def vocationDef(request):
if request.method == 'GET':
q = Vocation.objects.all().order_by('id')
pg = PageNumberPagination()
p = pg.paginate_queryset(queryset=q, request=request)
# 序列化
serializer = VocationSerializer(instance=p, many=True)
return Response(serializer.data)
elif request.method == 'POST':
data = request.data
id = data['name']
data['name'] = PersonInfo.objects.filter(id=id).first()
instance = Vocation.objects.filter(id=data.get('id', 0))
if instance:
# 修改数据
VocationSerializer().update(instance, data)
else:
# 创建数据
VocationSerializer().create(data)
return Response('Done', status=status.HTTP_201_CREATED)
class VocationClass(APIView):
def get(self, request):
q = Vocation.objects.all().order_by('id')
pg = PageNumberPagination()
p = pg.paginate_queryset(queryset=q, request=request)
# 将分页后的数据传递给 VocationSerializer,生成JSON数据对象
serializer = VocationSerializer(instance=p, many=True)
# 返回对象 有 Rest Framework 框架实现
return Response(serializer.data)
def post(self, request):
"""修改或新增"""
request_body = request.data
print(request_body) # {'id': 1, 'job': '软件工程师1', 'title': 'Python开发', 'payment': '10000', 'name': 2}
personinfo_id = request_body['name']
request_body['name'] = PersonInfo.objects.filter(id=personinfo_id).first() # first 返回的是一个obj
print(request_body) # {'id': 1, 'job': '软件工程师2', 'title': 'Python开发', 'payment': '10000', 'name': <PersonInfo: Tim>}
instance = Vocation.objects.filter(id=request_body.get('id', 0))
if instance:
# 修改数据
VocationSerializer().update(instance, request_body)
else:
# 创建数据
VocationSerializer().create(request_body)
return Response('Done', status=status.HTTP_201_CREATED)
vocationDef 视图函数验证:
查询到前2条数据
新增一条数据:
结果:
模型序列化类 ModelSerializer
序列化类 Serializer 可以与模型结合使用, 从而实现模型的数据读写操作。但是序列化类 Serializer 定义的字段必须与模型字段互相契合,否则在使用过程中很容易提示异常信息。为了简化序列化类的定义过程,Django Rest Framework 定义序列化类 ModelSerializer 。
使用案例:
# index\serializers.py
from rest_framework import serializers
from .models import Vocation
class VocationSerializer(serializers.ModelSerializer):
class Meta:
model = Vocation
fields = '__all__'
# fields = {'id', 'job', 'title', 'payment', 'name'}
属性model 将 模型Vocation 与 ModelSerializer 进行绑定,属性fields 用于设置哪些模型字段转化为 序列化字段,属性值'all' 代表模型所有字段转化为序列化字段,如果只设置部分模型字段,属性fields 的值就可以使用元组或列表。
下一步重新定义视图函数 和视图类, 使用模型序列化类 VocationSerializer 实现模型 Vocation 的 API 接口
# index\views.py
@api_view(['GET', 'POST'])
def vocationDef(request):
if request.method == 'GET':
q = Vocation.objects.all().order_by('id')
pg = PageNumberPagination()
p = pg.paginate_queryset(queryset=q, request=request)
# 序列化
serializer = VocationSerializer(instance=p, many=True)
return Response(serializer.data)
elif request.method == 'POST':
vocation_id = request.data.get('id', 0)
operation = Vocation.objects.filter(id=vocation_id).first()
serializer = VocationSerializer(data=request.data)
if serializer.is_valid():
if operation:
# 修改数据
data = request.data
id = data['name']
data['name'] = PersonInfo.objects.filter(id=id).first()
serializer.update(operation, data)
else:
# save
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=404)
class VocationClass(APIView):
def get(self, request):
q = Vocation.objects.all().order_by('id')
pg = PageNumberPagination()
p = pg.paginate_queryset(queryset=q, request=request)
# 将分页后的数据传递给 VocationSerializer,生成JSON数据对象
serializer = VocationSerializer(instance=p, many=True)
# 返回对象 有 Rest Framework 框架实现
return Response(serializer.data)
def post(self, request):
"""修改或新增"""
vocation_id = request.data.get('id', 0)
operation = Vocation.objects.filter(id=vocation_id).first()
serializer = VocationSerializer(data=request.data)
if serializer.is_valid():
if operation:
# 修改数据
data = request.data
id = data['name']
data['name'] = PersonInfo.objects.filter(id=id).first() # vocation的 外键name,关联上person obj
serializer.update(operation, data) # operation: 更新行, data:按data数据进更新
else:
# 新增数据
serializer.save()
return Response(serializer.errors, status=404)
序列化的嵌套使用
# index\serializers.py
class PersonInfoSerializer(serializers.ModelSerializer):
class Meta:
model = PersonInfo
fields = '__all__'
class VocationSerializer(serializers.ModelSerializer):
name = PersonInfoSerializer()
class Meta:
model = Vocation
fields = {'id', 'job', 'title', 'payment', 'name'}
def create(self, validated_data):
name = validated_data['name']
person_info_id = name.get('id', 0)
p = PersonInfo.objects.filter(id=person_info_id).first()
if not p:
# 新建personinfo
p = PersonInfo.objects.create(**name)
validated_data['name'] = p
v = Vocation.objects.create(**validated_data)
return v
def update(self, instance, validated_data):
personinfo_data = validated_data['name']
person_info_id = personinfo_data.get('id', 0)
p = PersonInfo.objects.filter(id=person_info_id).first()
if p:
# 如果存在personinfo 更新personinfo
p = PersonInfo.objects.filter(id=person_info_id).update(**personinfo_data)
# 再更新 vocation
validated_data['name'] = p
v = Vocation.objects.filter(validated_data['id']).update(**validated_data)
return v
# index\views.py
@api_view(['GET', 'POST'])
def vocationDef(request):
if request.method == 'GET':
q = Vocation.objects.all().order_by('id')
pg = PageNumberPagination()
p = pg.paginate_queryset(queryset=q, request=request)
# 序列化
serializer = VocationSerializer(instance=p, many=True)
return Response(serializer.data)
elif request.method == 'POST':
vocation_id = request.data.get('id', 0)
operation = Vocation.objects.filter(id=vocation_id).first()
serializer = VocationSerializer(data=request.data)
if serializer.is_valid():
if operation:
serializer.update(operation, request.data)
else:
# save
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=404)
class VocationClass(APIView):
def get(self, request):
q = Vocation.objects.all().order_by('id')
pg = PageNumberPagination()
p = pg.paginate_queryset(queryset=q, request=request)
# 将分页后的数据传递给 VocationSerializer,生成JSON数据对象
serializer = VocationSerializer(instance=p, many=True)
# 返回对象 有 Rest Framework 框架实现
return Response(serializer.data)
def post(self, request):
"""修改或新增"""
vocation_id = request.data.get('id', 0)
operation = Vocation.objects.filter(id=vocation_id).first()
serializer = VocationSerializer(data=request.data)
if serializer.is_valid():
if operation:
serializer.update(operation, request.data)
else:
# 新增数据
serializer.save()
return Response(serializer.errors, status=404)
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/18188130