ModelSerializer
serializers.ModelSerializer
是 Django REST framework(DRF)里的一個強大工具,它能極大簡化序列化和反序列化 Django 模型實例的流程。下面從多個方面詳細介紹它:
1. 基本概念
序列化是把 Django 模型實例轉化為 Python 原生數據類型(像字典、列表等),進而能方便地轉換為 JSON、XML 等格式用于傳輸;反序列化則是將接收到的數據轉換回 Django 模型實例。ModelSerializer
會自動依據模型的字段定義來生成序列化器的字段,減少了手動編寫序列化器字段的工作量。
2. 基本用法
假設你有一個簡單的 Django 模型 Book
:
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=100)published_date = models.DateField()def __str__(self):return self.title
可以創建一個對應的 ModelSerializer
:
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']
在上述代碼里,Meta
類的 model
屬性指定要序列化的模型,fields
屬性指定要包含在序列化結果中的字段。
3. 常用屬性和方法
Meta
類屬性
model
:指定要序列化的 Django 模型。fields
:指定要包含在序列化結果中的字段,可以是字段名的列表或字符串'__all__'
(表示包含模型的所有字段)。exclude
:指定要排除的字段,不能與fields
同時使用。read_only_fields
:指定只讀字段,這些字段在反序列化時會被忽略。extra_kwargs
:用于為特定字段提供額外的參數,例如設置字段的required
、write_only
等屬性。
示例:
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'read_only_fields = ['id']extra_kwargs = {'title': {'required': True},'author': {'write_only': True}}
序列化方法
data
:返回序列化后的 Python 原生數據類型。
book = Book.objects.first()
serializer = BookSerializer(book)
print(serializer.data)
is_valid()
:驗證反序列化的數據是否有效。
data = {'title': 'New Book', 'author': 'John Doe', 'published_date': '2023-01-01'}
serializer = BookSerializer(data=data)
if serializer.is_valid():book = serializer.save()
else:print(serializer.errors)
save()
:保存反序列化后的數據,創建或更新模型實例。
4. 自定義序列化行為
可以通過重寫序列化器的方法來自定義序列化和反序列化行為。
重寫 to_representation
方法
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'def to_representation(self, instance):data = super().to_representation(instance)data['title'] = data['title'].upper()return data
重寫 create
和 update
方法
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = '__all__'def create(self, validated_data):# 自定義創建邏輯return Book.objects.create(**validated_data)def update(self, instance, validated_data):# 自定義更新邏輯instance.title = validated_data.get('title', instance.title)instance.author = validated_data.get('author', instance.author)instance.published_date = validated_data.get('published_date', instance.published_date)instance.save()return instance
5. 優點
- 代碼簡潔:自動生成序列化器字段,減少了手動編寫的工作量。
- 一致性:序列化器的字段與模型的字段保持一致,方便維護。
- 驗證功能:自動提供基本的驗證功能,確保數據的有效性。
總之,serializers.ModelSerializer
是 Django REST framework 中非常實用的工具,能讓你更高效地處理 Django 模型的序列化和反序列化。
在 Django REST framework(DRF)里,ModelSerializer
中的 update
方法主要用于處理更新現有模型實例的邏輯。當你使用序列化器來更新一個已存在的模型對象時,update
方法會被調用。下面為你詳細介紹它的作用、工作機制以及使用示例。
作用
update
方法的核心作用是接收經過驗證的數據,把這些數據應用到已有的模型實例上,并且保存更新后的實例。它是序列化器在處理 PUT
或者 PATCH
請求時的關鍵部分,能夠幫助你定制模型實例更新的具體邏輯。
工作機制
- 當你調用序列化器的
save
方法并且傳入一個已存在的模型實例時,序列化器會自動調用update
方法。 update
方法接收兩個參數:instance
:代表要更新的模型實例。validated_data
:是一個字典,包含經過驗證的要更新的數據。
- 在
update
方法內部,你可以從validated_data
里提取數據,把這些數據賦給instance
的相應字段,然后調用instance.save()
方法保存更新后的實例。
示例代碼
下面是一個簡單的示例,展示了如何在 ModelSerializer
中重寫 update
方法:
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']def update(self, instance, validated_data):# 更新實例的字段instance.title = validated_data.get('title', instance.title)instance.author = validated_data.get('author', instance.author)instance.published_date = validated_data.get('published_date', instance.published_date)# 保存更新后的實例instance.save()return instance
代碼解釋
instance.title = validated_data.get('title', instance.title)
:這行代碼嘗試從validated_data
中獲取title
字段的值,如果validated_data
中存在title
字段,就將其賦值給instance.title
;如果不存在,就保持instance.title
的原有值。instance.save()
:調用save
方法將更新后的實例保存到數據庫中。return instance
:返回更新后的實例。
自定義更新邏輯
你可以在 update
方法中添加自定義的更新邏輯,例如在更新某些字段時執行額外的操作,或者根據特定條件更新不同的字段。
def update(self, instance, validated_data):if 'title' in validated_data:# 在更新標題時執行額外的操作new_title = validated_data['title'].upper()instance.title = new_titleif 'author' in validated_data:# 檢查作者是否合法if len(validated_data['author']) > 5:instance.author = validated_data['author']instance.published_date = validated_data.get('published_date', instance.published_date)instance.save()return instance
在這個例子中,當更新 title
字段時,會將新標題轉換為大寫;更新 author
字段時,會檢查作者名字的長度是否大于 5。
綜上所述,update
方法為你提供了一種靈活的方式來定制模型實例的更新邏輯,以滿足特定的業務需求。
ForeignKey
在 Django 中,models.ForeignKey
是一個非常重要的字段類型,用于在模型之間創建多對一(Many-to-One)的關聯關系。下面將從多個方面對其進行詳細介紹。
1. 基本概念
多對一關系表示一個模型的多個實例可以關聯到另一個模型的一個實例。例如,在一個博客應用中,多篇文章(Article
)可以屬于同一個作者(Author
),那么文章和作者之間就是多對一的關系。models.ForeignKey
就是用來在 Django 模型中定義這種關系的。
2. 基本語法
from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)def __str__(self):return self.nameclass Article(models.Model):title = models.CharField(max_length=200)author = models.ForeignKey(Author, on_delete=models.CASCADE)def __str__(self):return self.title
在上述代碼中,Article
模型中的 author
字段是一個 ForeignKey
,它指向 Author
模型。這意味著每篇文章都關聯到一個作者。
3. 參數說明
to
- 作用:指定關聯的模型。可以是模型類本身,也可以是模型類的字符串表示(如
'app_label.ModelName'
)。 - 示例:
author = models.ForeignKey('myapp.Author', on_delete=models.CASCADE)
on_delete
- 作用:定義當關聯的對象被刪除時,當前對象應該如何處理。這是一個必需的參數。
- 常見選項:
models.CASCADE
:級聯刪除。當關聯的對象被刪除時,與之關聯的所有對象也會被刪除。例如,當一個作者被刪除時,他所寫的所有文章都會被刪除。models.PROTECT
:保護模式。如果有關聯的對象存在,不允許刪除關聯的對象,會拋出ProtectedError
異常。models.SET_NULL
:將關聯字段設置為NULL
。前提是該字段必須允許為空(null=True
)。例如,當一個作者被刪除時,他所寫的文章的author
字段會被設置為NULL
。models.SET_DEFAULT
:將關聯字段設置為默認值。前提是該字段必須有默認值(default=...
)。models.SET()
:將關聯字段設置為指定的值或調用指定的函數返回的值。models.DO_NOTHING
:不做任何處理。可能會導致數據庫中的外鍵約束錯誤。
related_name
- 作用:定義從關聯模型反向查詢時使用的名稱。默認情況下,Django 會自動生成一個反向查詢的名稱,格式為
modelname_set
(例如,article_set
)。使用related_name
可以自定義這個名稱。 - 示例:
class Article(models.Model):title = models.CharField(max_length=200)author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')
現在可以通過 author.articles.all()
來獲取該作者的所有文章。
null
- 作用:指定該字段是否可以為空。如果設置為
True
,則允許該字段在數據庫中存儲NULL
值。 - 示例:
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)
blank
- 作用:指定在表單驗證時該字段是否可以為空。如果設置為
True
,則在表單中該字段可以不填寫。 - 示例:
author = models.ForeignKey(Author, on_delete=models.CASCADE, blank=True)
4. 反向查詢
通過 ForeignKey
建立的關聯關系,可以進行反向查詢。例如,有了上述的 Article
和 Author
模型,可以這樣進行反向查詢:
author = Author.objects.get(name='John Doe')
articles = author.article_set.all() # 如果沒有指定 related_name
# 或者
articles = author.articles.all() # 如果指定了 related_name='articles'
5. 數據庫層面
在數據庫中,ForeignKey
字段會被存儲為一個整數,這個整數是關聯模型實例的主鍵值。例如,Article
表中的 author
字段會存儲對應的 Author
實例的 id
。
6. 注意事項
- 當使用
ForeignKey
時,要確保on_delete
參數設置合理,避免出現數據不一致的問題。 - 頻繁的級聯刪除可能會導致數據丟失,使用時要謹慎。
綜上所述,models.ForeignKey
是 Django 中實現多對一關系的重要工具,通過合理使用其參數,可以靈活地管理模型之間的關聯。
ModelViewSet
在 Django REST framework(DRF)里,viewsets.ModelViewSet
是一個強大且實用的工具,它簡化了基于 Django 模型構建 RESTful API 的過程。下面我會詳細講解 viewsets.ModelViewSet
及其相關的 viewsets
模塊。
1. viewsets
模塊概述
viewsets
模塊是 Django REST framework 提供的一組視圖集類,它們把不同的視圖邏輯(如列表視圖、詳情視圖、創建視圖、更新視圖、刪除視圖等)組合在一起,讓你能夠以一種更簡潔、高效的方式構建 API。視圖集可以根據不同的 HTTP 請求方法(如 GET
、POST
、PUT
、DELETE
等)自動處理對應的操作。
2. ModelViewSet
簡介
ModelViewSet
是 viewsets
模塊中的一個核心類,它繼承自多個不同的混合類(如 CreateModelMixin
、RetrieveModelMixin
、UpdateModelMixin
、DestroyModelMixin
、ListModelMixin
),這些混合類為 ModelViewSet
提供了完整的 CRUD(創建、讀取、更新、刪除)操作功能。
3. 基本用法
假設你有一個簡單的 Django 模型 Book
:
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=100)published_date = models.DateField()def __str__(self):return self.title
你可以創建一個對應的 ModelViewSet
來處理這個模型的 API 操作:
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializerclass BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializer
這里的 BookSerializer
是一個序列化器,用于將 Book
模型實例序列化為 JSON 數據,以及將 JSON 數據反序列化為 Book
模型實例。以下是一個簡單的序列化器示例:
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']
4. 路由配置
為了讓 BookViewSet
能夠響應 HTTP 請求,需要進行路由配置。Django REST framework 提供了 routers
模塊來簡化路由配置:
from rest_framework import routers
from .views import BookViewSetrouter = routers.DefaultRouter()
router.register(r'books', BookViewSet)urlpatterns = router.urls
這樣,BookViewSet
就會自動處理以下幾種類型的請求:
GET /books/
:獲取所有書籍的列表。POST /books/
:創建一本新的書籍。GET /books/{id}/
:獲取指定 ID 的書籍詳情。PUT /books/{id}/
:更新指定 ID 的書籍的所有字段。PATCH /books/{id}/
:部分更新指定 ID 的書籍的字段。DELETE /books/{id}/
:刪除指定 ID 的書籍。
5. 方法和屬性
queryset
:指定要處理的模型實例集合,通常是一個查詢集(QuerySet)。serializer_class
:指定用于序列化和反序列化的序列化器類。get_queryset()
:可以重寫這個方法來動態地返回不同的查詢集,例如根據用戶權限過濾數據。
class BookViewSet(viewsets.ModelViewSet):serializer_class = BookSerializerdef get_queryset(self):# 只返回已發布的書籍return Book.objects.filter(published=True)
perform_create()
:可以重寫這個方法來在創建新實例時執行額外的操作,例如記錄日志。
class BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializerdef perform_create(self, serializer):# 在創建書籍時記錄日志print(f"Creating a new book: {serializer.validated_data['title']}")serializer.save()
6. 優點
- 代碼簡潔:通過繼承
ModelViewSet
,可以用很少的代碼實現完整的 CRUD 操作,減少了重復代碼。 - 可維護性高:將不同的視圖邏輯封裝在一個類中,使得代碼結構更加清晰,易于維護和擴展。
- 自動生成路由:結合
routers
模塊,可以自動生成 API 的路由,簡化了路由配置。
綜上所述,viewsets.ModelViewSet
是 Django REST framework 中一個非常實用的工具,能夠幫助你快速、高效地構建功能完整的 RESTful API。