zoukankan      html  css  js  c++  java
  • Django REST framework

    Django REST framework 序列化

    DRF 序列化的本质

    Django ORM对象 --> JSON格式的数据 ==>此过程是序列化
    类似json模块中dumps()

    JSON格式的数据 --> Django ORM的数据 ==>此过程是反序列化
    类似json模块中loads

    DRF中序列化工具

    from rest_framework.serializers import Serializer
    from rest_framework.serializers import MoselSerializer
    

    类比Django中的form组件
    Django form --> HTML表单
    HTML表单 -->ORM数据

    安装DRF

    pip install djangorestframework
    

    添加rest_framework应用

    注册app(非必须的)
    
    INSTALLED_APPS = [
    ...
    'rest_framework',
    

    ]

    定义Serializer

    class BookInfoSerializer(serializers.Serializer):
    	pass
    or
    class BookInfoSerializer(serializers.MoselSerializer):
    	pass
    

    使用DRF序列化器 示例

    表结构

    class Article(models.Model):
        id = models.AutoField(primary_key=True)
        title = models.CharField(max_length=64)
        create_time = models.DateField(auto_now=True)
        type = models.SmallIntegerField(
            choices=((1, '原创'), (2, '转载')),
            default=1
        )
        source = models.ForeignKey(to='Source', on_delete=models.CASCADE)
        tag = models.ManyToManyField(to='Tag')
    
    
    class Source(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32, unique=True, error_messages={"unique": '校区名称不能重复'})
    
    
    class Tag(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
    
    
    class Comment(models.Model):
        content = models.CharField(max_length=255)
    article = models.ForeignKey(to='Article', on_delete=models.CASCADE)
    

    一. 单表的GET和POST

    路由

    url(r'source/', views.SourceView.as_view()),
    

    序列化类

    class SourceSerializer(serializers.ModelSerializer):
    
        def validate_name(self, value):
            if '草' in value:
                raise ValidationError('不符合社会主义核心价值观')
            return value
    
        class Meta:
            model = models.Source
            fields = "__all__"
    

    视图

    class SourceView(APIView):
    
        def get(self, request, *args, **kwargs):
            res = {"code": 0}
            all_source = models.Source.objects.all()
            ser_obj = SourceSerializer(all_source, many=True)
            res["data"] = ser_obj.data
            return Response(res)
    
        def post(self, request, *args, **kwargs):
            res = {"code": 0}
            ser_obj = SourceSerializer(data=request.data)
            if ser_obj.is_valid():
                # 数据没问题
                ser_obj.save()
                return Response(res)
            else:
                res["code"] = 1
                res["error"] = ser_obj.errors
                return Response(res)
    

    二. 外键的GET和POST

    路由

    url(r'comment/', views.Comment.as_view()),
    

    序列化

    class CommentSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Comment
            fields = "__all__"
            extra_kwargs = {
                "content": {"error_messages": {"required": "评论内容不能为空"}},
                "article": {"error_messages": {"required": "文章不能为空"}}
            }
    

    视图

    class Comment(APIView):
        def get(self, request, *args, **kwargs):
            res = {"code": 0}
            all_data = models.Comment.objects.all()
            ser_obj = CommentSerializer(all_data, many=True)
            res["data"] = ser_obj.data
            return Response(res)
    
        def post(self, request, *args, **kwargs):
            res = {"code": 0}
            ser_obj = CommentSerializer(data=request.data)
            if ser_obj.is_valid():
                ser_obj.save()
            else:
                res["code"] = 1
                res["error"] = ser_obj.errors
            return Response(res)
    

    多对多的GET和POST

    路由

    url(r'article/', views.ArticleList.as_view()),
    

    序列化

    class TagSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = models.Tag
            fields = "__all__"
    
    
    class ArticleSerializer(serializers.ModelSerializer):
        type = serializers.CharField(source="get_type_display")
        tag = TagSerializer(many=True)
    
        class Meta:
            model = models.Article
            fields = ["id", "title", "type", "source", "tag"]
    
    
    class ArticleWriteSerializer(serializers.ModelSerializer):
    
        class Meta:
            model = models.Article
            fields = "__all__"
            extra_kwargs = {
                "tag": {
                    "error_messages": {
                        "does_not_exist": '"{pk_value}"对应的tag对象不存在。'
                    }
                }
            }
    

    三. 视图

    class ArticleList(APIView):
        def get(self, request, *args, **kwargs):
            res = {"code": 0}
            article_list = models.Article.objects.all()
            ser_obj = ArticleSerializer(article_list, many=True)
            res["data"] = ser_obj.data
            return Response(res)
    
        def post(self, request, *args, **kwargs):
            res = {"code": 0}
            ser_obj = ArticleWriteSerializer(data=request.data)
            if ser_obj.is_valid():
                ser_obj.save()
            else:
                res["code"] = 1
                res["error"] = ser_obj.errors
            return Response(res)
    

    四. 超链接的序列化

    路由

    urlpatterns = [
        url(r'articlelinked/', views.ArticleLinked.as_view()),,
        url(r'source/(?P<pk>d+)', views.SourceDetailView.as_view(), name='source-detail'),
    ]
    

    序列化

    class ArticleHyperlinkedSerializer(serializers.HyperlinkedModelSerializer):
        source = serializers.HyperlinkedIdentityField(view_name='source-detail', lookup_field='source_id', lookup_url_kwarg='pk')
    
        class Meta:
            model = models.Article
            fields = ["id", "type", "title", "source"]
            depth = 1
    

    视图

    class ArticleLinked(APIView):
        def get(self, request, *args, **kwargs):
            res = {"code": 0}
            article_list = models.Article.objects.all()
            ser_obj = ArticleHyperlinkedSerializer(article_list, many=True, context={'request': request})
            res["data"] = ser_obj.data
            return Response(res)
    

    序列化补充 跨表的序列化##

    方法一

    class ModelCourseCategoryView(serializers.ModelSerializer):
        # price = serializers.SerializerMethodField()
        # learn_num = serializers.SerializerMethodField()
        
    
        # def get_price(self, obj):
        #     price_obj = obj.price_policy.all().filter(valid_period=723).first()
        #     return price_obj.price
        #
        # def get_learn_num(self, obj):
        #     return obj.order_details.count()
    

    方法二

    source 支持被序列化对象的点操作

    learn_num = serializers.IntegerField(source='order_details.count')
    course_detail_id = serializers.IntegerField(source='coursedetail.id')
    

    方法三###

    to_representation终级方法

    # 修改序列化结果的终极方法
    def to_representation(self, instance):
        # 调用父类的同名方法把序列化的结果拿到
        data = super().to_representation(instance)
        # 针对序列化的结果做一些自定制操作
        # 判断当前这个课程是否有永久有效的价格
        price_obj = instance.price_policy.all().filter(valid_period=999).first()
        if price_obj:
            # 有永久有效的价格
            data['has_price'] = True
            data['price'] = price_obj.price
            else:
                # 没有永久有效的价格策略
                data['has_price'] = False
                return data
  • 相关阅读:
    Linux 磁盘挂载和mount共享
    Socket编程实践(8) --Select-I/O复用
    JavaScript 作用域链图具体解释
    扩展MongoDB C# Driver的QueryBuilder
    Gray Code
    Android网络编程Socket【实例解析】
    设计模式之:代理模式
    LOL英雄联盟代打外挂程序-java实现
    MySQL系列:innodb源代码分析之线程并发同步机制
    linux压缩打包
  • 原文地址:https://www.cnblogs.com/konghui/p/10351905.html
Copyright © 2011-2022 走看看