zoukankan      html  css  js  c++  java
  • DjangoRestFramework之序列化组件

    一 . serializers

    from rest_framework.views import APIView
    from app01 import models
    from rest_framework.response import Response
    from rest_framework import serializers
    
    # 使用serializers 需要先定义一个类,类里面的内容要和models一致
    class BookSerializers(serializers.Serializer):
        title = serializers.CharField(max_length=16)
        price = serializers.IntegerField()
    
    class BookHandle(APIView):
    
        def get(self, request):
            book_msg = models.Books.objects.all()
            res = BookSerializers(book_msg, many=True)  # 当res里面有多个对象(query_set)的时候要指定many=true(必填)
            print(res.data)
            return Response(res.data)  # 可以用rest_framework里面的Response
    
        def post(self, request):
            # print('post方法==>', request.data)
            res = BookSerializers(data=request.data, many=False)
            if res.is_valid():  # 这个是对传过来数据与models里面的字段是否对应进行验证
                models.Books.objects.create(**res.data)
                return Response(res.data)  # 按照API接口规范,数据存储成功后要返回
            return Response(res.errors)

    二 . 学了单表的,来一波跨表的序列化 

    from django.db import models
    
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        age = models.IntegerField()
    
    class AuthorDetail(models.Model):
        nid = models.AutoField(primary_key=True)
        birthday = models.DateField()
        telephone = models.BigIntegerField()
        addr = models.CharField(max_length=64)
    
    class Publish(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=32)
        email = models.EmailField()
    
    class Book(models.Model):
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        publishDate = models.DateField()
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)  # 多对一到Publish表
        authors = models.ManyToManyField(to='Author', )  # 多对多到Author表

      多对一的外键序列化展示,在没有写source之前

     

      写了source之后

      

      多对多的外键序列化展示

      

      

      

     三 . 用ModelSerializer序列化

         基于ModelSerializer的get,post,put,delete的用法

     1 from rest_framework.response import Response
     2 from rest_framework.views import APIView
     3 from rest_framework import serializers
     4 from app01 import models
     5 
     6 class BookSerializer(serializers.ModelSerializer):
     7     class Meta:
     8         model = models.Book
     9         fields = '__all__'
    10 
    11     # 关于外键序列化要写在这个类里面
    12     # 下面这两个变量千万不要和数据库的名字相同,否则会由于read_only=True被剔除,导致报错
    13     publish_list = serializers.CharField(source='publish.name')  # book表中publish外键,多对一
    14     authors_list = serializers.SerializerMethodField()  # 多对多的写法
    15 
    16     def get_authors_list(self, obj):  # 函数名格式必须是get_这个类中对应的属性名,obj就是下面book_obj_list里的每一个对象
    17         lst = []
    18         authors_list = obj.authors.all()
    19         for author in authors_list:
    20             dic = {}
    21             dic['name'] = author.name
    22             lst.append(dic)
    23         return lst
    24 
    25 class BookHandle(APIView):
    26     # 获取所有数据
    27     def get(self, request):
    28         book_obj_list = models.Book.objects.all()
    29         book_res = BookSerializer(book_obj_list, many=True)
    30         return Response(book_res.data)
    31 
    32     def post(self, request):
    33         # print('post发来的数据=>', request.data)
    34         res = BookSerializer(data=request.data, many=False)
    35         if res.is_valid():
    36             res.save()
    37             return Response(res.data)
    38         else:
    39             return Response(res.errors)
    40 
    41 # 带参数的单独写一个类,也会有一个单独的视图函数
    42 class HaveCanShu(APIView):
    43     # 更新数据
    44     def put(self, request, id):
    45         old_obj = models.Book.objects.filter(pk=id).first()
    46         res = BookSerializer(data=request.data, many=False, instance=old_obj)
    47         if res.is_valid():
    48             res.save()
    49             return Response(res.data)
    50         else:
    51             return Response(res.errors)
    52 
    53     def delete(self, request, id):
    54         models.Book.objects.filter(pk=id).delete()
    55         return Response('')  # 执行删除操作后,要返回空字符串
    56 
    57     def get(self, request, id):
    58         book_obj = models.Book.objects.get(pk=id)
    59         book_res = BookSerializer(book_obj, many=False)
    60         return Response(book_res.data)
    get, post, put, delete

    四 . 为了避免代码重复接下来有个进化版的视图函数

      all_serializers.py文件

    首先我们先把所有的序列化类单独放一个py文件中,我这里放到了all_serializers.py文件中.
    from rest_framework import serializers
    from app01 import models
    
    class PublishSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Publish
            fields = '__all__'

      视图函数

    from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin, 
        RetrieveModelMixin
    from rest_framework import generics
    
    # ListModelMixin 获取所有数据操作
    # RetrieveModelMixin 获取一条数据操作
    # DestroyModelMixin 删除一体数据操作
    # UpdateModelMixin 更新一条数据操作
    # CreateModelMixin 添加一条数据操作
    
    class PublishHandle(ListModelMixin, CreateModelMixin, generics.GenericAPIView):
        queryset = models.Publish.objects.all()  # 变量名必须是这个
        serializer_class = PublishSerializer  # 变量名必须是这个
    
        def get(self, request):
            return self.list(request)
    
        def post(self, request):
            return self.create(request)
    
    # 有参数的写一个类
    class CPublishHandle(UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, generics.GenericAPIView):
        queryset = models.Publish.objects.all()  # 变量名必须是这个
        serializer_class = PublishSerializer  # 变量名必须是这个
    
        def put(self, request, *args, **kwargs):
            return self.update(request, *args, **kwargs)
    
        def delete(self, request, *args, **kwargs):
            return self.destroy(request, *args, **kwargs)
    
        def get(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)

      URL

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    
        url(r'^publishes/$', views.PublishHandle.as_view()),
        url(r'^publishes/(?P<pk>d+)/', views.CPublishHandle.as_view()),  # 参数一定要这么写
    ]

    五 . 上边还是有冗余,来一款再进化版

      all_serializers.py文件

    from rest_framework import serializers
    from app01 import models
    
    class AuthorSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Author
            fields = '__all__'

      视图函数 

    from app01 import models
    from app01.all_serializers import AuthorSerializer
    from rest_framework import generics
    
    class AuthorHandle(generics.ListCreateAPIView):
        queryset = models.Author.objects.all()  # 变量名必须是这个
        serializer_class = AuthorSerializer  # 变量名必须是这个
    
    class CAuthorHandle(generics.RetrieveUpdateDestroyAPIView):
        queryset = models.Author.objects.all()  # 变量名必须是这个
        serializer_class = AuthorSerializer  # 变量名必须是这个

      URL

    url(r'^authors/$', views.AuthorHandle.as_view()),
    url(r'^authors/(?P<pk>d+)/', views.CAuthorHandle.as_view()),

    六 . 终极进化版

      上面还是有一点重复,下面来一个终级进化版

        all_serializers.py文件

    class AuthorSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Author
            fields = '__all__'

        视图函数

    from rest_framework.viewsets import ModelViewSet
    from app01 import models
    
    # 只写一个类就可以啦
    class CAuthorHandle(ModelViewSet):
        queryset = models.Author.objects.all()  # 变量名必须是这个
        serializer_class = AuthorSerializer  # 变量名必须是这个

        URL

    url(r'^authors/$', views.CAuthorHandle.as_view({
         'get': 'list',
         'post': 'create'
    })),
    url(r'^authors/(?P<pk>d+)/', views.CAuthorHandle.as_view({
         'get': 'retrieve',
         'put': 'update',
         'delete': 'destroy',
    })),

      

  • 相关阅读:
    第02组 Beta冲刺 总结
    第02组 Beta冲刺 (5/5)
    第02组 Beta冲刺 (4/5)
    第02组 Beta冲刺 (3/5)
    第02组 Beta冲刺 (2/5)
    第02组 Beta冲刺 (1/5)
    关于IE6中做兼容的那点事。
    一个ajax同步与异步引发的血案。
    浅谈Jquery中的bind(),live(),delegate(),on()绑定事件方式
    浅谈Dictionary用法
  • 原文地址:https://www.cnblogs.com/attila/p/10802342.html
Copyright © 2011-2022 走看看