回顾一 APIView
首先说一下序列化 serializers
class UserModelSerializer(serializers.Serializer): key = serializers.CharField() cos_path = serializers.CharField()
# 对于这样的序列化,我们有几个字段就写几个字段--只能序列化和表单验证 不能存数据库里
class UserModelSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__"
# 对于这样的序列化,可以通过serializer对象 点 save 保存到数据库里
# 对于POST 请求
from rest_framework.response import Response from rest_framework import serializers class UserModelSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserView(APIView):def post(self,request,*args,**kwargs):
# 序列化做校验 ser = UserModelSerializer(data=request.data) if ser.is_valid():
# 存入数据库的两种形式 ser.save(添加额外的值) # models.UserInfo.objects.create(**ser.validated_data) ser.save(user_id=1) return Response(ser.data) return Response(ser.errors)
# GET请求 class UserModelSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserView(APIView): def get(self,request,*args,**kwargs): user_list = models.UserInfo.objects.all() # 做校验 这里的user_list 是多条要用下面的形式 要是单条的 要写成 mang=False 局部更新的话 添加一个 partial=True ser = UserModelSerializer(instance=user_list,many=True) return Response(ser.data)
回顾二 ListAPIView / CreateAPIView
1. CreateAPIView
class NewTestModelSerializer(serializers.ModelSerializer): class Meta: model = models.News fields = "__all__" class NewTestView(CreateAPIView): serializer_class = NewTestModelSerializer # 直接添加就完事了 --------------------------------------------------------------- 如果我们在添加前面干点事的话 重写post方法 class NewTestModelSerializer(serializers.ModelSerializer): class Meta: model = models.News fields = "__all__" class NewTestView(CreateAPIView): def post(self,request,*args,**kwargs):
print(123)
return super().post(self,request,*args,**kwargs)
对于自己要多存一个值到数据库
# 解释见下图
class NewTestModelSerializer(serializers.ModelSerializer): class Meta: model = models.News fields = "__all__" class NewTestView(CreateAPIView,ListAPIView): serializer_class = NewTestModelSerializer queryset = models.News.objects.filter(id__gt=4) def perform_create(self, serializer): serializer.save(uid=str(uuid.uuid4()))
对于用于只展示几个字段的需求
class NewTestModelSerializer(serializers.ModelSerializer): class Meta: model = models.News fields = ["id","name","age"]
2. ListAPIView
class NewTestModelSerializer(serializers.ModelSerializer): class Meta: model = models.News fields = "__all__" class NewTestView(ListAPIView): serializer_class = NewTestModelSerializer queryset = models.News.objects.filter(id__gt=4)
# 对于 ListAPIView 需要一个 查出来的数据 queryset
补充一 fields和exclude的区别
通过fields和exclude定制页面展示数据。
需求:只显示用户表的id,name,age的数据,其他不显示。
class NewTestModelSerializer(serializers.ModelSerializer): class Meta: model = models.News # fields = ["id","name",'age'] # 只展示这三个字段 # fields = "__all__" # 展示所有的字段 exclude = ['gender'] # 不展示这个字段 class NewTestView(ListAPIView): serializer_class = NewTestModelSerializer queryset = models.User.objects.all()
需求:数据库有5个字段,显示6个字段
两种方式 我分开写
class NewTestModelSerializer(serializers.ModelSerializer):
xx = serializers.CharField(source='id') class Meta: model = models.News fields = "__all__" # fields = ['id','name','age','gender','phone','xx',] class NewTestView(ListAPIView): serializer_class = NewTestModelSerializer queryset = models.User.objects.all()
最后形式 [ {id:1,name:'xxx',age:18... xx:1}, {id:2,name:'xxx',age:11... xx:2}, {id:3,name:'xxx',age:99, xx:3}, ]
方式二
class NewTestModelSerializer(serializers.ModelSerializer): x1 = serializers.SerializerMethodField() class Meta: model = models.News fields = "__all__" # fields = ['id','name','age','gender','phone','x1'] def get_x1(self,obj): return obj.id class NewTestView(ListAPIView): serializer_class = NewTestModelSerializer queryset = models.User.objects.all()
最后形式 [ {id:1,name:'xxx',age:18... x1:1}, {id:2,name:'xxx',age:11... x1:2}, {id:3,name:'xxx',age:99, x1:3}, ]
补充二 read_only
添加时不要,查看时候需要
需求:编写两个接口 添加(3字段)、获取列表(5个字段)
两种形式 看标颜色的地方
class NewTestModelSerializer(serializers.ModelSerializer): # phone = serializers.CharField(source='phone',read_only=True) # email = serializers.CharField(source='email',read_only=True) class Meta: model = models.News fields = "__all__" read_only_fields = ['phone','email',] class NewTestView(CreateAPIView, ListAPIView): serializer_class = NewTestModelSerializer queryset = models.User.objects.all()
形式 添加: { name:'xx', age:'19', gender:1 } 获取: [ {name:'xx',age:'xx',gender:'',phone:'xx',email:xxx} ]
补充三 复杂需求
添加时用一个serializers、列表时用一个serializers
class NewTestModelSerializer1(serializers.ModelSerializer): class Meta: model = models.News fields = "__all__" class NewTestModelSerializer2(serializers.ModelSerializer): class Meta: model = models.News fields = "__all__" class NewTestView(CreateAPIView, ListAPIView): queryset = models.User.objects.all() def get_serializer_class(self): if self.request.method == 'POST': return NewTestModelSerializer1 if self.request.method == 'GET': return NewTestModelSerializer2
补充四serializers嵌套
{ "cover":"https://123.png", "content":"学习xuexi", "address":"北京", "topic":"1", "imageList":[ { "key":"123.png", "cos_path":"https://12344" }, { "key":"123.png", "cos_path":"https://12344" } ] }
我们有一段数据,下面的代码中 CreateNewsModelSerializer 校验了第一层数据 第二层的imageList数据没法校验 用 CreateNewsTopicModelSerializer 来校验
class CreateNewsTopicModelSerializer(serializers.Serializer):
"""imageList的数据必须是这两个字段""" key = serializers.CharField() cos_path = serializers.CharField() class CreateNewsModelSerializer(serializers.ModelSerializer): imageList = CreateNewsTopicModelSerializer(many=True) class Meta: model = models.News exclude = ['user', 'viewer_count', 'comment_count',"favor_count"] def create(self, validated_data): # 把imageList切走 image_list = validated_data.pop('imageList') # 创建New表中的数据 news_object = models.News.objects.create(**validated_data) data_list = models.NewsDetail.objects.bulk_create( [models.NewsDetail(**info, news=news_object) for info in image_list] ) news_object.imageList = data_list if news_object.topic: news_object.topic.count += 1 news_object.save() return news_object class NewsView(CreateAPIView): """ 发布动态 """ serializer_class = CreateNewsModelSerializer def perform_create(self, serializer): # 只能保存:News表中的数据() # 调用serializer对象的save(先调用create) new_object = serializer.save(user_id=1) return new_object