13 Serializer與ModelSerializer區別

1、ModelSerializer序列化
一、定義ModelSerializer序列化器html

針對models設計和聲明序列化類

from rest_framework import serializers
from .models import Book, Publisher前端

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 與Book表對應python

# 這三種狀況不能同時使用
    # 1.取所有字段
    fields = "__all__"

    # 2.自定義包含字段
    # fields = ["id", "title", "pub_time"]
    # 輸出:[{"id": 1, "title": "python開發", "pub_time": "2011-08-27"},...]

    # 3.排除某些字段
    # exclude = ["id", "category","author", "publisher"]
    # 輸出:[{"title": "python開發", "pub_time": "2011-08-27"},...]

  須要注意的是:取所有字段、取自定義字段、排除某些字段這三種篩選不能同時使用。django

二、外鍵關係的序列化
  注意:當序列化類META定義了depth時,這個序列化類中引用字段(外鍵)則自動變爲只讀。api

  depth 表明找嵌套關係的第幾層。ide

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 與Book表對應
fields = "all"
depth = 1
  添加depth前,顯示效果:post

  

  添加depth後,顯示效果:ui

  

  由上圖可知,只會查看嵌套深度一層的內容。設計

三、自定義字段
  不少字段默認顯示的是選擇的key值,但要給用戶展現的是value值。rest

  所以能夠聲明一些字段來覆蓋默認字段來進行自定製。

class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到對應中文

class Meta:
    model = Book         # 與Book表對應
    fields = "__all__"

  顯示效果以下所示:

  

四、Meta中其餘關鍵字參數
  官方文檔地址:https://www.django-rest-framework.org/api-guide/serializers/

(1)指定只讀字段
  但願將多個字段指定爲只讀。推薦使用快捷的Meta選項read_only_fields,而不是顯式地使用read_only=True屬性添加每一個字段。示例以下所示:

class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)

class Meta:
    model = Book
    fields = "__all__"
    depth = 1
    read_only_fields = ["id"]

  模型字段有設置 editable=False, AutoField 字段默認設置爲只讀,不須要添加到 read_only_fields 選項。

(2)給字段添加額外參數——extra_kwargs
  使用extra_kwargs參數爲ModelSerializer添加或修改原有的選項參數---字典格式。

示例一:

class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)

class Meta:
    model = Book
    fields = "__all__"
    depth = 1
    read_only_fields = ["id"]
    extra_kwargs = {"title": {"validators": [my_validate,]}}

示例二:

class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['email', 'username', 'password']
extra_kwargs = {'password': {'write_only': True}}
  若是字段已在序列化程序類中顯式聲明,則該extra_kwargs選項將被忽略。

五、post和patch請求
  因爲depth會讓外鍵變成只讀,因此定義一個序列化的類,其實只要去掉depth就能夠了。

class BookSerializer(serializers.ModelSerializer):
chapter = serializers.CharField(source="get_chapter_display", read_only=True)

class Meta:
    model = Book
    fields = "__all__"
    # fields = ["id", "title", "pub_time"]
    # exclude = ["user"]
    # 分別是全部字段 包含某些字段 排除某些字段
    read_only_fields = ["id"]
    extra_kwargs = {"title": {"validators": [my_validate,]}}

六、SerializerMethodField
  外鍵關聯的對象有不少字段是用不到的,都傳給前端會有數據冗餘。須要本身去定製序列化外鍵對象的那些字段。

針對models設計和聲明序列化類

from rest_framework import serializers
from .models import Book, Publisher

class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到對應中文

class Meta:
    model = Book         # 與Book表對應
    fields = "__all__"

  查看頁面 http://127.0.0.1:8000/books/list,顯示效果以下所示:

  

  添加 SerializerMethodField的使用,獲取顯示外聯字段:

class BookSerializer(serializers.ModelSerializer):
category = serializers.CharField(source="get_category_display") # 找到對應中文

# SerializerMethodField的使用,獲取顯示外聯字段
publisher = serializers.SerializerMethodField()
author= serializers.SerializerMethodField()

def get_author(self, obj):
    authors_query_set = obj.author.all()   # 拿到全部做者信息
    return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set]   # 列表推導式

def get_publisher(self, obj):
    # obj是咱們序列化的每一個Book對象
    publisher_obj = obj.publisher   # 正向查詢
    return {'id': publisher_obj.id}

class Meta:
    model = Book         # 與Book表對應
    fields = "__all__"

  顯示效果以下所示:

  

2、ModelSerializer反序列化
一、ModelSerializer原生POST請求  
  再將 SerDemo/serializers.py 下 BookSerializer 恢復爲原生狀態:

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book # 與Book表對應
fields = "all"
  不用自定義create方法,可直接提交提交post請求以下:

  

  數據新增成功,以下所示:

  

二、SerializerMethodField改寫
class BookSerializer(serializers.ModelSerializer):
# SerializerMethodField的使用,獲取顯示外聯字段
category_display = serializers.SerializerMethodField(read_only=True) # 從新定義,避免重寫,影響反序列化
publisher_info = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)

def get_category_display(self, obj):
    return obj.get_category_display()  # ORM方法獲取中文

def get_authors(self, obj):
    authors_query_set = obj.author.all()   # 拿到全部做者信息
    return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set]   # 列表推導式

def get_publisher_info(self, obj):
    # obj是咱們序列化的每一個Book對象
    publisher_obj = obj.publisher   # 正向查詢
    return {'id': publisher_obj.id}

class Meta:
    model = Book         # 與Book表對應
    fields = "__all__"

  顯示效果以下所示:

  

  能夠從上圖看到,除了顯示了category_display、authors、publisher_info,也顯示了category、publisher、author。

三、extra_kwargs配置字段參數
class BookSerializer(serializers.ModelSerializer):
# SerializerMethodField的使用,獲取顯示外聯字段
category_display = serializers.SerializerMethodField(read_only=True) # 從新定義,避免重寫,影響反序列化
publisher_info = serializers.SerializerMethodField(read_only=True)
authors = serializers.SerializerMethodField(read_only=True)

def get_category_display(self, obj):
    return obj.get_category_display()  # ORM方法獲取中文

def get_authors(self, obj):
    authors_query_set = obj.author.all()   # 拿到全部做者信息
    return [{"id": authors_obj.id, "name": authors_obj.name} for authors_obj in authors_query_set]   # 列表推導式

def get_publisher_info(self, obj):
    # obj是咱們序列化的每一個Book對象
    publisher_obj = obj.publisher   # 正向查詢
    return {'id': publisher_obj.id}

class Meta:
    model = Book         # 與Book表對應
    fields = "__all__"
    extra_kwargs = {
        "category": {"write_only": True},   # 避免直接改寫
        "publisher": {"write_only": True},
        "author": {"write_only": True}
    }

  如此就再也不顯示category、publisher、author了,顯示效果以下所示:

  

3、Serializer與ModelSerializer區別

本文轉載於https://www.cnblogs.com/xiugeng/p/11460855.html

相關文章
相關標籤/搜索