restful api 回顾
回顾一 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现