一、引言:什么是 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 的 Prefetch
和 depth
選項優化嵌套關系查詢。
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 序列化器 |
高性能需求 | 使用 和 |
字段驗證 | 使用 DRF 序列化器的 方法 |
嵌套結構 | 使用 或 |
安全性 | 使用 和 控制字段權限 |
代碼復用 | 抽取公共字段、繼承 實現復用 |
十、總結
Django 提供了兩種強大的序列化機制:
- 原生序列化器:適合數據導出、遷移等場景;
- DRF 序列化器:適合構建 RESTful API、支持字段驗證、嵌套關系、自定義字段等高級功能。
掌握序列化機制,是構建高效、可維護、安全的 Django Web 應用的重要基礎。