继承APIView+Response实现 Publish的5个接口
views.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Publish
class PublishView(APIView):
def get(self,request):
publish_list=Publish.objects.all()
l=[]
for publish in publish_list:
l.append({'name':publish.name,'addr':publish.addr})
return Response({'code':100,'msg':'ok','result':l})
def post(self,request):
# publish=Publish.objects.create(**request.data)
publish=Publish.objects.create(name=request.data.get('name'),addr=request.data.get('addr'))
return Response({'code':100,'msg':'ok','result': {'name':publish.name,'addr':publish.addr}})
class PublishDetailView(APIView):
def get(self,request,pk):
publish=Publish.objects.filter(pk=pk).first()
return Response({'code':100,'msg':'ok','result': {'name':publish.name,'addr':publish.addr}})
def put(self,request,pk):
publish = Publish.objects.filter(pk=pk).first()
publish.name=request.data.get('name')
publish.addr=request.data.get('addr')
publish.save()
return Response({'code':100,'msg':'ok','result': {'name':publish.name,'addr':publish.addr}})
def delete(self,request,pk):
Publish.objects.filter(pk=pk).delete()
return Response({'code':100,'msg':'ok'})
以上代码做序列化和反序列化都是自己写的,没有做数据校验。
drf 提供的序列化器,实现 序列化 反序列化 数据校验
使用步骤:
1 写个py文件,叫serializer.py (可以随便命名)
2 写个类,继承serializers.Serializer
3 在类中写要序列化的字段
class PublishSerializer(serializers.Serializer):
# 写字段,要序列化的字段
name = serializers.CharField()
addr = serializers.CharField()
id = serializers.IntegerField()
4 在视图类中使用,完成 序列化
-多条
-ser = PublishSerializer(instance=publish_list, many=True)
-ser.data 序列化后的数据
-单条:
-ser = PublishSerializer(instance=publish)
-ser.data 序列化后的数据
序列化类的使用
序列化类文件 serializer.py
from rest_framework import serializers
class PublishSerializer(serializers.Serializer):
# 写字段,要序列化的字段
name = serializers.CharField()
# addr = serializers.CharField()
id = serializers.IntegerField()
视图类 views.py
from .serializer import PublishSerializer
class PublishView(APIView):
def get(self, request):
publish_list = Publish.objects.all()
ser = PublishSerializer(instance=publish_list, many=True) # 如果序列化多条,要many=True
return Response({'code': 100, 'msg': '查询所有成功', 'results': ser.data})
class PublishDetailView(APIView):
def get(self, request, pk):
publish = Publish.objects.filter(pk=pk).first()
ser = PublishSerializer(instance=publish) # 单个不写many=True
return Response(
{'code': 100, 'msg': '查询单条成功', 'results': ser.data})
路由文件 urls.py
urlpatterns = [
path('publish/', views.PublishView.as_view()),
path('publish/<int:pk>', views.PublishDetailView.as_view()),
]
序列化类反序列化校验
三层规则
第一层:字段自己的校验
addr=serializers.CharField(max_length=32,min_length=3)
第二层:局部钩子
def validate_addr(self,addr): if 'hb' in addr: raise ValidationError('地址中不能有hb') return addr
第三层:全局钩子
def validate(self,attrs): if attrs.get('name') == attrs.get('addr'): raise Exception('出版社名和地址不能一样') return attrs
在视图类中
def post(self,request): ser=PublishSerializer(data=request.data) if ser.is_valid(): #做三层数据校验 print(ser.data) else: print(ser.errors) return Response({'code':100,'msg':'ok'})
序列化类保存
# 使用步骤:
1 在序列化类中,必须重写 create,完成真正的保存
# 保存,必须重写create
def create(self, validated_data):
# validated_data 校验过后的数据---》多传的数据,在这没有
publish = Publish.objects.create(**validated_data)
return publish # 不要忘了返回新增的对象---》后续会拿着这个对象做序列化 ser.data--->根据它做序列化的
2 在视图类中,数据校验通过后,调用ser.save()
ser.save() # 使用序列化类保存--》会报错---》咱们没有指定保存到那个表--》必须重写create方法
# 修改功能,也要校验和保存
# 修改使用步骤
1 在序列化类中,必须重写 update,完成真正的修改
def update(self, instance, validated_data): # {name:上海出版社,add:上海地址}
instance.name=validated_data.get('name')
instance.addr=validated_data.get('addr')
instance.save() # publish 对象的save---》保存到数据中
return instance
2 视图类中
ser = PublishSerializer(instance=publish, data=request.data)
ser.save() # 虽然新增或修改都是调用save,但是内部做了判断