欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

02-序列化组件的使用及接口设计-中

一.serializers.Serializer使用实例

1.通过序列化组件进行接口设计

  1.1设计协定

                GET       127.0.0.1:8000/books/     # 获取所有数据,返回值: [{}, {}]
                GET       127.0.0.1:8000/books/{id} # 获取一条数据,返回值:{}
                POST      127.0.0.1:8000/books/     # 新增一条数据,返回值:{}
                PUT       127.0.0.1:8000/books/{id} # 修改数据,返回值:{}
                DELETE    127.0.0.1:8000/books/{id} # 删除数据,返回空

 

  1.2创建models.py,数据库表创建

from django.db import models

# Create your models here.


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


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 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", related_query_name="book_query", on_delete=models.CASCADE)
    # 多对多字段
    authors = models.ManyToManyField(to="Author")
View Code

 

 

  1.3创建urls.py

from django.urls import re_path
from serializer import views

urlpatterns = [
    re_path(r'books/$', views.BookView.as_view()),
]
View Code

 

 

  1.4创建序列化类app_serializers.py

from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    # nid = serializers.CharField(max_length=32)
    title = serializers.CharField(max_length=128)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    # 外键字段, 显示__str__方法的返回值
    publish = serializers.CharField(max_length=32, source="publish.city")
    # authors = serializers.CharField(max_length=32) # book_obj.authors.all()

    # 多对多字段需要自己手动获取数据,SerializerMethodField()
    authors_list = serializers.SerializerMethodField()

    def get_authors_list(self, book_obj):
        author_list = list()

        for author in book_obj.authors.all():
            author_list.append(author.name)

        return author_list

    def create(self, book_obj):
        return book_obj
View Code

 

  1.5在views中使用序列化类views.py

class BookView(APIView):
    def get(self, request):
        # 第三步,获取queryset
        origin_data = Book.objects.all()

        # 第四步,开始序列化
        serialized_data = BookSerializer(origin_data, many=True)

        return Response(serialized_data.data)

    def post(self, request):

        verified_data = BookSerializer(data=request.data)

        if verified_data.is_valid():
            book = verified_data.save()
            authors = Author.objects.filter(nid__in=request.data['authors'])
            book.authors.add(*authors)
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)



class BookFilterView(APIView):
    def get(self, request, nid):
        book_obj = Book.objects.get(pk=nid)

        serialized_data = BookSerializer(book_obj, many=False)

        return Response(serialized_data.data)

    def put(self, request, nid):
        book_obj = Book.objects.get(pk=nid)

        verified_data = BookSerializer(data=request.data, instance=book_obj)

        if verified_data.is_valid():
            verified_data.save()
            return Response(verified_data.data)
        else:
            return Response(verified_data.errors)

    def delete(self, request, nid):
        book_obj = Book.objects.get(pk=nid).delete()

        return Response()
View Code

 

二.ModelSerializer

通常,你会希望序列化器紧密的映射到Django模型定义上。

ModelSerializer 类提供了一个快捷方式,可以自动创建具有与模型字段对应的字段的 Serializer

ModelSerializer 类继承于 Serializer 类,在父类上实现了以下的功能:

  • 它将根据模型自动生成一组字段。
  • 它将自动为序列化器生成验证器,例如 unique_together 验证器。
  • 它包含默认简单实现的 .create() 和 .update() 方法。

1.声明ModelSerializer

from rest_framework import serializers

from app01.models import Book


class BookSerialize(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ('id',
                  'title',
                  'price',
                  'authors',
                  'publish',
                  'authors_list',
                  'publish_name',
                  'publish_city'
                  )
        # 附加关键字参数
        extra_kwargs = {
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }
        # 只读字段
        read_only_fields = ('publish_name', 'publish_city')

    # 显式定义字段
    publish_name = serializers.CharField(max_length=32, source='publish.name')
    publish_city = serializers.CharField(max_length=32, source='publish.city')

    # 多对多字段需要定义get_<field_name>方法处理数据
    authors_list = serializers.SerializerMethodField()

    def get_authors_list(self, book_obj):
        authors = [author.name for author in book_obj.authors.all()]
        return authors

 

2.指定只读字段

您可能希望将多个字段指定为只读。您可以使用快捷的 Meta 选项 read_only_fields,而不是使用 read_only=True 属性显式的添加每个字段。

该选项应该是字段名称的列表或元组,并声明如下:

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ('id', 'account_name', 'users', 'created')
        read_only_fields = ('account_name',)

 

 

模型中已经设置 editable=False 的字段和默认就被设置为只读的 AutoField 字段都不需要添加到 read_only_fields 选项中。

3.附加关键字参数

还有一个快捷方式允许您使用 extra_kwargs 选项在字段上指定任意附加关键字参数。与 read_only_fields 的情况一样,这意味着不需要在序列化器中显式声明该字段。

class CreateUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('email', 'username', 'password')
        extra_kwargs = {'password': {'write_only': True}}

    def create(self, validated_data):
        user = User(
            email=validated_data['email'],
            username=validated_data['username']
        )
        user.set_password(validated_data['password'])
        user.save()
        return user

 

三.BaseSerializer

BaseSerialAlgisher 类,可以用来方便地支持可选的序列化和反序列化样式。

该类实现与 Serializer 类相同的基本 API:

  • .data —— 返回传出的基元表示。
  • .is_valid() —— 反序列化并验证传入的数据。
  • .validated_data —— 返回经过验证的传入数据。
  • .errors —— 返回在验证期间的任何错误。
  • .save() —— 将验证的数据保存到对象实例中。

可以重写四种方法,这取决于你希望序列化器类支持的功能:

  • .to_representation() —— 重写它以支持序列化,用于读取操作。
  • .to_internal_value() —— 重写它以支持反序列化,以用于写入操作。
  • .create() 和 .update() —— 重写其中一个或两个以支持保存实例。

因为此类提供了与 Serializer 类相同的接口,所以您可以像使用常规的 Serializer 或 ModelSerializer 一样使用现有的通用的基于类的视图。

在执行此操作时您将注意到的唯一区别是 BaseSerializer 类不会在可浏览的 API 中生成 HTML 表单。这是因为它们返回的数据不包括允许每个字段被渲染成合适的 HTML 输入的所有字段信息。

 四.序列化器字段

官网说明

posted on 2018-12-08 10:44  Louiszj  阅读(127)  评论(0编辑  收藏  举报

导航