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

 

 

 

 
posted @ 2020-03-10 22:41  流年中渲染了微笑  阅读(180)  评论(0编辑  收藏  举报