Django 序列化詳解:從 Model 到 JSON,全面掌握數據轉換機制

一、引言:什么是 Django 序列化?

在 Web 開發中,序列化(Serialization) 是指將復雜的數據結構(如數據庫模型對象)轉換為可傳輸的格式(如 JSON、XML、YAML 等),以便在客戶端與服務器之間進行通信。

Django 提供了多種序列化機制,幫助開發者輕松地將模型數據轉換為結構化數據格式,常用于構建 RESTful API、數據導出、緩存等場景。

本文將深入講解 Django 的序列化機制,涵蓋:

  • Django 內置序列化器(serializers
  • Django REST Framework(DRF)序列化器
  • 自定義字段與驗證邏輯
  • 嵌套關系處理
  • 性能優化建議

二、Django 內置序列化器詳解

Django 自帶了一個簡單的序列化模塊 django.core.serializers,支持 JSON、XML、YAML 等格式。

1. 使用示例

from django.core import serializers
from myapp.models import Book# 序列化為 JSON
books = Book.objects.all()
json_data = serializers.serialize("json", books)# 反序列化
for obj in serializers.deserialize("json", json_data):obj.save()

2. 輸出格式說明

輸出的 JSON 數據包含模型名稱、主鍵和字段值:

[{"model": "myapp.book","pk": 1,"fields": {"title": "Django 入門","author": "張三","published": "2023-01-01"}}
]

3. 優點與限制

優點

缺點

簡單易用

無法自定義字段名

支持反序列化

不支持嵌套關系

適合數據遷移或導出

不適合構建 REST API


三、Django REST Framework(DRF)序列化器詳解

在構建 RESTful API 時,Django REST Framework(DRF) 提供了更強大、靈活的序列化器系統,支持字段驗證、嵌套關系、分頁、自定義渲染等。

1. 安裝 DRF

pip install djangorestframework

settings.py 中添加:

INSTALLED_APPS += ['rest_framework']

2. 定義一個基礎序列化器

from rest_framework import serializers
from myapp.models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'

3. 序列化單個對象或查詢集

book = Book.objects.get(id=1)
serializer = BookSerializer(book)
print(serializer.data)books = Book.objects.all()
serializer = BookSerializer(books, many=True)
print(serializer.data)

輸出示例:

{"id": 1,"title": "Django 入門","author": "張三","published": "2023-01-01"
}

四、自定義字段與驗證邏輯

1. 自定義字段類型

class BookSerializer(serializers.ModelSerializer):title_upper = serializers.SerializerMethodField()class Meta:model = Bookfields = ['id', 'title', 'title_upper', 'author', 'published']def get_title_upper(self, obj):return obj.title.upper()

2. 添加驗證邏輯

class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published']def validate_title(self, value):if len(value) < 3:raise serializers.ValidationError("書名必須大于3個字符")return value

3. 全局驗證

def validate(self, data):if data['title'] == data['author']:raise serializers.ValidationError("書名不能與作者相同")return data

五、處理嵌套關系(Nested Relationships)

1. 外鍵關系

class AuthorSerializer(serializers.ModelSerializer):class Meta:model = Authorfields = ['id', 'name']class BookSerializer(serializers.ModelSerializer):author = AuthorSerializer()class Meta:model = Bookfields = ['id', 'title', 'author', 'published']

2. 反向關系(Related Field)

class AuthorSerializer(serializers.ModelSerializer):books = BookSerializer(many=True, read_only=True)class Meta:model = Authorfields = ['id', 'name', 'books']

3. 可寫嵌套關系

默認情況下,嵌套關系是只讀的。如需寫入,需重寫 create()update() 方法。

class BookSerializer(serializers.ModelSerializer):author = AuthorSerializer()class Meta:model = Bookfields = ['id', 'title', 'author', 'published']def create(self, validated_data):author_data = validated_data.pop('author')author, created = Author.objects.get_or_create(**author_data)return Book.objects.create(author=author, **validated_data)

六、性能優化:減少數據庫查詢

1. 使用 select_related()prefetch_related()

books = Book.objects.select_related('author').all()
serializer = BookSerializer(books, many=True)

2. 避免 N+1 查詢問題

使用 DRF 的 Prefetchdepth 選項優化嵌套關系查詢。

class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'depth = 1  # 自動展開外鍵關系(不推薦用于復雜結構)

3. 使用緩存減少重復查詢

from django.core.cache import cachedef get_books():books = cache.get('books_list')if not books:books = Book.objects.all()cache.set('books_list', books, 60 * 15)  # 緩存15分鐘return books

七、DRF 序列化器高級用法

1. HyperlinkedModelSerializer(生成 API 鏈接)

class BookSerializer(serializers.HyperlinkedModelSerializer):class Meta:model = Bookfields = ['url', 'title', 'author', 'published']

2. 使用 to_representation() 自定義輸出

class BookSerializer(serializers.ModelSerializer):def to_representation(self, instance):data = super().to_representation(instance)data['custom_field'] = f"書籍:{instance.title}"return data

3. 使用 to_internal_value() 自定義輸入

class BookSerializer(serializers.ModelSerializer):def to_internal_value(self, data):data['title'] = data['title'].strip()return super().to_internal_value(data)

八、DRF 序列化器 vs Django 原生序列化器對比

功能

Django 原生序列化器

DRF 序列化器

支持 JSON、XML、YAML

?

?(默認 JSON)

支持反序列化

?

?

支持字段驗證

?

?

支持嵌套關系

?

?

支持自定義字段

?

?

支持 REST API 構建

?

?

支持分頁

?

?

支持性能優化(如 select_related)

?

?

九、最佳實踐建議

場景

建議

數據遷移、導出

使用 Django 原生序列化器

構建 REST API

使用 DRF 序列化器

高性能需求

使用 select_related()

prefetch_related()

字段驗證

使用 DRF 序列化器的 validate()

方法

嵌套結構

使用 SerializerMethodField

Prefetch

安全性

使用 read_only_fields

extra_kwargs

控制字段權限

代碼復用

抽取公共字段、繼承 ModelSerializer

實現復用


十、總結

Django 提供了兩種強大的序列化機制:

  • 原生序列化器:適合數據導出、遷移等場景;
  • DRF 序列化器:適合構建 RESTful API、支持字段驗證、嵌套關系、自定義字段等高級功能。

掌握序列化機制,是構建高效、可維護、安全的 Django Web 應用的重要基礎。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92236.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92236.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92236.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

茶葉蛋大冒險小游戲流量主微信抖音小程序開源

游戲特點 響應式設計&#xff1a;完美適配各種移動設備屏幕尺寸 直觀的觸摸控制&#xff1a;左右滑動屏幕控制茶葉蛋移動 中式風格元素&#xff1a; 茶葉蛋角色帶有裂紋紋理和可愛表情 筷子、蒸籠等中式廚房元素作為障礙物 八角、茶葉等香料作為收集物 鍋底火焰動畫效果 游戲機…

區分郵科工業交換機與路由器

在這個數字化的時代&#xff0c;我們每天都在享受著互聯網帶來的便利。無論是工作還是娛樂&#xff0c;網絡已經成為我們生活中不可或缺的一部分。然而&#xff0c;在這個看似簡單的背后&#xff0c;隱藏著兩個至關重要的設備——郵科工業交換機和路由器。它們就像網絡世界的雙…

【數據結構入門】數組和鏈表的OJ題(2)

目錄 1.回文鏈表 分析&#xff1a; 代碼&#xff1a; 2.相交鏈表 分析&#xff1a; 代碼&#xff1a; 3.環形鏈表 分析&#xff1a; 代碼&#xff1a; 面試提問&#xff1a; 4.環形鏈表II 分析1&#xff1a; 分析2&#xff1a; 代碼&#xff1a; 5.隨機鏈表的復…

文件包含篇

web78 第一題filter偽協議直接讀源碼即可 ?filephp://filter/convert.base64-encode/resourceflag.php web79 flag.php的php無法用大小寫繞過&#xff0c;所以用Php://input只讀流 import requests url "http://fadb524a-f22d-4747-a35c-82f71e84bba7.challenge.ctf.sho…

互作蛋白組學技術對比:鄰近標記與傳統IP-MS、Pull down-MS優勢對比

在生命科學領域&#xff0c;蛋白質間的相互作用構成了生命活動的核心網絡&#xff0c;驅動著信號傳導、基因調控、代謝途徑等關鍵過程。為了繪制這幅復雜的“分子互作地圖”&#xff0c;科學家們開發了多種技術&#xff0c;其中免疫共沉淀結合質譜&#xff08;IP-MS&#xff09…

(ZipList入門筆記一)ZipList的節點介紹

ZipList是 Redis 中一種非常緊湊、節省內存的數據結構 Ziplist&#xff08;壓縮列表&#xff09; 的內部內存布局。它被用于存儲元素較少的 List、Hash 和 Zset。 下面我們來詳細介紹每一個節點的含義&#xff1a; 1. zlbytes (ziplist bytes) 含義&#xff1a; 整個壓縮列…

Unix 發展史概覽

這里是一個簡明清晰的 Unix 發展史概覽&#xff0c;涵蓋從起源到現代的重要節點和演變過程。Unix 發展史概覽 1. Unix 起源&#xff08;1969年&#xff09; 貝爾實驗室&#xff1a;Ken Thompson 和 Dennis Ritchie 開發出 Unix 操作系統。最初設計目標&#xff1a;簡潔、可移植…

基于coze studio開源框架二次定制開發教程

目錄 一、 項目介紹 1.1 什么是Coze Studio 1.2 功能清單 1.3對比商業版本 二、 功能定開說明 2.1 技術棧簡介 2.2 項目架構

RHCE認證題解

考前說明請勿更改 IP 地址。DNS 解析完整主機名&#xff0c;同時也解析短名稱。? 所有系統的 root 密碼都是 redhat? Ansible 控制節點上已創建用戶賬戶 devops。可以使用 ssh 訪問? 所需的所有鏡像保存在鏡像倉庫 utility.lab.example.compodman 可使用下述賬號登錄使用 用…

調用com對象的坑

1、諫言 最近我在弄64位調用32位dll的問題&#xff0c;在幾種IPC之間&#xff0c;最后考慮了調用COM 畢竟我們只在windows平臺 2、第一坑–修改編譯后都需要重新注冊&#xff0c;注冊表 一直以為只需要編譯就好了&#xff0c;結果調用沒反應、報錯什么的&#xff0c;需要先撤銷…

【Python】PyQt 實現 TreeWidget 多級聯動選擇邏輯,打造素材搜索自定義樹形控件!

在開發自己的寫作素材管理工具時,我遇到了一個非常典型但又略顯棘手的 UI 問題: ?? 如何實現一個“可自由勾選分類標簽”的樹形結構界面,支持父子節點自動聯動勾選,提升用戶體驗? 雖然 PyQt 的 QTreeWidget 是構建多層分類結構的好幫手,但默認卻不具備父子節點的自動級…

27-數據倉庫與Apache Hive-2

1.數倉開發語言概述 理論上來說&#xff0c;任何一款編程語言只要具備讀寫數據、處理數據的能力&#xff0c;都可以用于數倉的開發。比如大家耳熟能詳的C、java、Python等&#xff1b; 關鍵在于編程語言是否易學、好用、功能是否強大。遺憾的是上面所列出的C、Python等編程語言…

軟件測試——接口自動化

測試中的自動化分為兩類&#xff1a; 1.ui自動化&#xff08;web、移動端&#xff09;2.接口自動化 前面的博客中&#xff0c;我們已經講解了web端的ui自動化&#xff0c;感興趣的同學可以去看看&#xff1a;軟件測試——自動化測試常見函數_自動化測試代碼編寫-CSDN博客 今…

Flask一個用戶同時只能在一處登錄實現

場景&#xff1a;web頁面如果多人用同一賬號同時登錄操作&#xff0c;可能會導致數據等的混亂甚至出現故障。并且可能損害開發者的利益。為此&#xff0c;本篇文章就講下如何實現同一賬戶同時僅能一個地方登錄操作。 思路&#xff1a;1. 用戶登陸時生成token&#xff08;uuid.u…

聯發科芯片組曝高危漏洞:越界寫入缺陷危及智能手機與物聯網設備安全

漏洞概況全球領先的芯片組制造商聯發科&#xff08;MediaTek&#xff09;近日發布最新產品安全公告&#xff0c;披露了影響其智能手機、物聯網設備及其他嵌入式系統芯片的多項安全漏洞。高危漏洞分析CVE-2025-20696 作為公告披露的首個且最嚴重的漏洞&#xff0c;該高危缺陷源于…

Android與Flutter混合開發:頁面跳轉與通信完整指南

Android與Flutter混合開發&#xff1a;頁面跳轉與通信完整指南 一、Android跳轉Flutter頁面的實現方式 1. 基礎跳轉方法 &#xff08;1&#xff09;使用全新引擎跳轉&#xff08;每次新建&#xff09; startActivity(FlutterActivity.withNewEngine().initialRoute("/home…

Web存儲技術詳解:sessionStorage、localStorage與Cookie

一、核心特性對比特性CookielocalStoragesessionStorage存儲大小4KB左右5-10MB5-10MB生命周期可設置過期時間永久存儲&#xff08;除非手動清除&#xff09;會話期間有效&#xff08;標簽頁關閉即清除&#xff09;作用域同源的所有窗口同源的所有窗口僅當前標簽頁自動發送每次H…

3. 為什么 0.1 + 0.2 != 0.3

總結 底層是二進制實現概述 在 JavaScript 中&#xff0c;0.1 0.2 的結果并不是精確的 0.3&#xff0c;而是 0.30000000000000004。這個現象并不是 JavaScript 的“bug”&#xff0c;而是由于浮點數在計算機底層的二進制表示方式導致的精度丟失問題。一、計算機如何表示小數&a…

股票數據接口哪家好?專業評測各主流接口的優勢與不足

Python股票接口實現查詢賬戶&#xff0c;提交訂單&#xff0c;自動交易&#xff08;1&#xff09; Python股票程序交易接口查賬&#xff0c;提交訂單&#xff0c;自動交易&#xff08;2&#xff09; 股票量化&#xff0c;Python炒股&#xff0c;CSDN交流社區 >>> 股票…

如何用分布式架構視角理解宇宙穩定性?從精細調參到微服務的類比思考

在調試一段多線程分布式代碼時&#xff0c;我忽然意識到一個不合理的事實&#xff1a;為什么現實世界這么穩定&#xff1f;為什么沒有“宇宙藍屏”或“感知崩潰”&#xff1f;為什么每天醒來&#xff0c;我們還能看到同樣的物理規律、感知同一個自我&#xff1f;站在程序員的角…