zoukankan      html  css  js  c++  java
  • Django Rest Framework 序列化接口(GET与POST)设计 (前期版)!

    定义序列化器(本质就是一个类),一般包括模型类的字段,有自己的字段类型规则。实现了序列化器后,就可以创建序列化对象以及查询集进行序列化操作,通过序列化对象.data来获取数据(不用自己构造字典,再返回Json数据)

    创建一个django项目;

    创建一个app,且名字为:books

     1 INSTALLED_APPS = [
     2     'django.contrib.admin',
     3     'django.contrib.auth',
     4     'django.contrib.contenttypes',
     5     'django.contrib.sessions',
     6     'django.contrib.messages',
     7     'django.contrib.staticfiles',
     8     'books',
     9     'rest_framework'
    10 ]
    settings.py
    from django.contrib import admin
    from django.urls import path
    from books import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('book/',views.BookView.as_view())
    ]
    urls.py
    from django.shortcuts import render, HttpResponse
    from . import models
    
    # 1.原生django序列化组件使用
    from django.views import View
    from django.core.serializers import serialize
    # 1.Django原生序列化的使用
    # class BookView(View):
    #     def get(self, request):
    #         # 获取queryset
    #         book_list = Book.objects.all()
    #         # 对queryset进行序列化
    #         serialize_data = serialize('json', book_list)
    #         # 返回序列化后的数据
    #         return HttpResponse(serialize_data)
    
    
    # 2.1-DRF序列化组件使用
    from rest_framework.views import APIView
    from rest_framework.response import Response
    # 在应用下新建一个文件:serizlizer.py 用来写相关需要序列化的数据
    # 导入serizlizer.py文件下的:BookSerizlizer类
    from .serizlizer import BookSerizlizer
    
    
    class BookView(APIView):
        def get(self, request):
            # 拿到书的对象数据
            book_obj = models.Book.objects.all()
            # 创造一个序列化器,传入书对象数据。
            serialized_data = BookSerizlizer(book_obj, many=True)
            # 返回DRF序列化后的数据.最后需要点data才能拿到结果
            return Response(serialized_data.data)
    
        # 访问127.0.0.1:8000/books/==>以下为页面拿到的数据(authors字段不正常,
        # 因为authors在数据库与book表是多对多字段,
        # 所以在serizlizer.py里面def一个方法来获取这项数据)
        '''    [
        {
            "nid": "1",
            "title": "python初级",
            "price": "188.00",
            "publish": "清华大学出版社",
            "authors": "serializer.Author.None"
        },
        {
            "nid": "2", 
            "title": "python中级",
            "price": "78.00",
            "publish": "清华大学出版社",
            "authors": "serializer.Author.None"
        },   
              ]
        '''
    
        def post(self, request):
            '''通过序列化组件进行post接口(提交一条数据)设计,步骤如下:
        - 定义post方法:在视图类中定义post方法;
        - 开始序列化:通过上面定义的序列化类,创建一个序列化对象,传入参数data=request.data(application/json)数据;
        - 校验数据:通过实例对象的is_valid()方法,对请求数据的合法性进行校验;
        - 保存数据:调用save()方法,将数据插入数据库;
        - 插入数据到多对多关系表:如果有多对多字段,手动插入数据到多对多关系表;
        - 返回:将插入的对象返回;
          '''
            serialized_data = BookSerizlizer(data=request.data)
            if serialized_data.is_valid():
                book = serialized_data.save()
                # 手动绑定多对多关系,也可以放到create方法中去
                authors = models.Author.objects.filter(nid__in=request.data['authors'])
                book.authors.add(*authors)
                return Response(serialized_data.data)
            else:
                return Response(serialized_data.errors)
    
    '''分析:上面这种方法有两个问题:一个是需要手动插入数据(写序列化类中写create方法),
    另一个是如果字段很多,写序列化类的字段也会变成一种负担,那么有没有更简单的方式呢?当然,
    那就是用ModelSerializer!所以我们需要修改一下serializer.py中的代码'''
    views.py
    from django.db import models
    
    # Create your models here.
    
    class Book(models.Model):
        nid = models.AutoField(primary_key=True)
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        publish = models.ForeignKey(to='Publish', related_name='book', on_delete=models.CASCADE)
        authors = models.ManyToManyField(to='Author')
    
    
    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()
    
        def __str__(self):
            return self.name
    
    
    class Author(models.Model):
        nid = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        age = models.IntegerField()
    
        def __str__(self):
            return self.name
    mdoels.py
    # 2.1-导入序列化模块.创造一个序列化数据的类
    from rest_framework import serializers
    
    #一版本的序列化类
    # class BookSerizlizer(serializers.Serializer):
    #     nid = serializers.CharField(max_length=32)
    #     title = serializers.CharField(max_length=128)
    #     price = serializers.IntegerField()
    #     publish = serializers.CharField(max_length=32)
    #     # authors = serializers.CharField(max_length=32)#authors为多对多字段,应该使用下面的方法
    #     authors = serializers.SerializerMethodField()
    #
    #     # 定义一个方法获取多对多字段数据,注意:get_必须与字段字段名称一致,否则报错。,并传入一个book对象
    #     def get_authors(self, book_obj):
    #         authors = []
    #         # book_obj.authors.all()拿到每本书对应的作者(比如:models.Book.objects.first().authors.all()拿到第一本书的作者)
    #         for author in book_obj.authors.all():
    #             # 把作者的名字添加进去,(author.name)
    #             authors.append(author.name)
    #         return authors
    
    #关于POST接口需要重新写一下BookSerizlizer类
    '''注意:因为多对多关系字段是我们自定义的,而且必须这样定义,返回的数据才有意义,
    而用户插入数据的时候,无法找到这个字段类型SerializerMethodField,
    所以,序列化类不能帮我们插入数据到多对多表,我们必须手动插入数据,!!!以上序列化类注释不用了!!!因此序列化类要做如下修改:'''
    #二版本序列化类
    # from .models import Book
    #
    # class BookSerizlizer(serializers.Serializer):
    #     # nid字段只需要传给客户端,用户提交不需要id,所以read_only=True
    #     nid = serializers.CharField(read_only=True, max_length=32)
    #     title = serializers.CharField(max_length=128)
    #     price  = serializers.DecimalField(max_digits=5, decimal_places=2)
    #     publish = serializers.CharField(max_length=32)
    #     # SerializerMethodField默认read_only=True
    #     authors = serializers.SerializerMethodField()
    #
    #         # 定义一个方法获取多对多字段数据,注意:get_必须与字段字段名称一致,否则报错。,并传入一个book对象
    #     def get_authors(self, book_obj):
    #         authors = []
    #         # book_obj.authors.all()拿到每本书对应的作者(比如:models.Book.objects.first().authors.all()拿到第一本书的作者)
    #         for author in book_obj.authors.all():
    #             # 把作者的名字添加进去,(author.name)
    #             authors.append(author.name)
    #         return authors
    #
    #     # 必须手动插入数据,因此post方法提交数据必须有create方法!
    #     def create(self, validated_data):
    #         print(validated_data) # validated_data为过滤之后的数据
    #         validated_data['publish_id'] = validated_data.pop('publish')
    #         book = Book.objects.create(**validated_data)
    #
    #         return book
    
    #三版本序列化类
    from . import models
    #使用ModelSerializer,post方法就不再依赖create方法
    class BookSerizlizer(serializers.ModelSerializer):
        class Meta:
            model = models.Book
            fields = (
                'title',
                'price',
                'publish',
                'authors',
                'author_list',
                'pubName',
                'pubCity'
            )
            extra_kwargs = {
                'publish':{'write_only':True},
                'authors':{'write_only':True}
            }
    
        pubName = serializers.CharField(max_length=32, read_only=True, source='publish.name')
        pubCity = serializers.CharField(max_length=32, read_only=True, source='publish.city')
    
        # 多对多字段
        author_list = serializers.SerializerMethodField()
    
        def get_author_list(self, book_obj):
            authors = list()
    
            for author in book_obj.authors.all():
                authors.append(author.name)
    
            return authors
    serizlizer.py
  • 相关阅读:
    WF4.0 Beta1 自定义跟踪
    WF4.0 Beta1 流程设计器与Activity Designer
    新版本工作流平台的 (二) 权限算法(组织结构部分)
    WF4.0 Beta1 WorkflowInvoker
    WF4.0 基础篇 (十) Collection 集合操作
    WF4.0 基础篇 (十五) TransactionScope 事物容器
    WF4.0 基础篇 (六) 数据的传递 Arguments 参数
    WF4B1 的Procedural Activity 之InvokeMethod , InvokeMethod<T> 使用
    WF4.0 Beta1 异常处理
    WF4.0 Beta1 变量 Variables
  • 原文地址:https://www.cnblogs.com/cou1d/p/12333340.html
Copyright © 2011-2022 走看看