在 Django REST Framework (DRF) 中,mixins.CreateModelMixin
、mixins.ListModelMixin
、GenericAPIView
和 GenericViewSet
是構建 API 視圖的核心組件。以下是對這些組件的主要方法及其職責的簡要說明,內容清晰且結構化:
1. mixins.CreateModelMixin
職責:提供創建模型實例的功能,通常用于處理 POST 請求以創建新的資源。
主要方法:
create(request, *args, **kwargs)
:- 功能:處理 POST 請求,創建并保存新的模型實例。
- 流程:
- 使用序列化器驗證請求數據。
- 如果數據有效,調用
perform_create
保存實例。 - 返回 201 Created 響應,包含創建的資源數據。
- 返回值:Response 對象,包含序列化后的新創建對象數據。
perform_create(serializer)
:- 功能:執行實際的保存操作,供子類重寫以添加自定義邏輯(如設置創建者的用戶 ID)。
- 默認行為:調用
serializer.save()
保存實例。
使用場景:實現“創建”功能,如添加新用戶、新文章等。
2. mixins.ListModelMixin
職責:提供列出所有資源的功能,通常用于處理 GET 請求以返回模型實例列表。
主要方法:
list(request, *args, **kwargs)
:- 功能:處理 GET 請求,返回查詢集的序列化數據。
- 流程:
- 獲取查詢集(通過
get_queryset()
)。 - 可選地應用分頁(通過
paginate_queryset
)。 - 使用序列化器序列化查詢集。
- 返回序列化數據(分頁或非分頁)。
- 獲取查詢集(通過
- 返回值:Response 對象,包含序列化后的對象列表。
使用場景:列出資源列表,如獲取所有用戶、所有文章等。
3. GenericAPIView
職責:DRF 的通用視圖基類,提供了核心功能(如查詢集、序列化器、分頁等)的配置和處理邏輯,適合自定義視圖。
主要方法:
get_queryset()
:- 功能:返回視圖使用的查詢集。
- 默認行為:使用類屬性
queryset
或需要子類重寫。
get_serializer_class()
:- 功能:返回視圖使用的序列化器類。
- 默認行為:使用類屬性
serializer_class
或需要子類重寫。
get_serializer(*args, **kwargs)
:- 功能:實例化并返回序列化器對象。
filter_queryset(queryset)
:- 功能:對查詢集應用過濾、分頁等操作。
- 默認行為:調用
filter_backends
進行過濾。
paginate_queryset(queryset)
:- 功能:對查詢集進行分頁處理。
- 返回值:分頁后的查詢集或 None(無分頁時)。
其他職責:
- 提供分頁、過濾、權限檢查等基礎設施。
- 支持動態配置序列化器和查詢集,靈活性高。
使用場景:需要自定義視圖邏輯時使用,結合 Mixins 或直接重寫方法。
4. GenericViewSet
職責:繼承自 GenericAPIView
和 ViewSet
,提供更高級別的視圖集功能,支持路由器自動生成 URL 路由,適合快速構建 RESTful API。
主要方法:
- 繼承了
GenericAPIView
的所有方法(如get_queryset
、get_serializer_class
等)。 - 額外提供 ViewSet 的特性:
as_view()
:動態綁定 HTTP 方法(如 GET、POST)到視圖方法(如list
、create
)。- 支持路由器(如
DefaultRouter
)自動生成 URL 模式。
- 通常與 Mixins 組合使用(如
CreateModelMixin
、ListModelMixin
)來實現具體功能。
職責擴展:
- 不直接綁定 HTTP 方法到 URL,需要通過路由器或手動配置。
- 提供更大的靈活性,適合復雜 API(如支持多種操作的資源)。
使用場景:快速構建 RESTful API,結合路由器生成標準化的 URL 模式。
總結對比
組件 | 主要方法 | 職責概述 | 使用場景 |
---|---|---|---|
CreateModelMixin | create , perform_create | 處理 POST 請求,創建新資源 | 創建資源(如添加新用戶) |
ListModelMixin | list | 處理 GET 請求,返回資源列表 | 列出資源(如獲取所有文章) |
GenericAPIView | get_queryset , get_serializer_class , etc. | 提供查詢集、序列化器等核心功能,供自定義視圖 | 自定義復雜視圖邏輯 |
GenericViewSet | 繼承 GenericAPIView 方法 + ViewSet 特性 | 結合 Mixins 和路由器快速構建 RESTful API | 快速開發標準化的 RESTful API |
注意事項
- Mixin 需要結合
GenericAPIView
或ViewSet
:Mixins 不獨立使用,需與GenericAPIView
或其子類(如GenericViewSet
)組合。 - 路由器與 ViewSet:
GenericViewSet
常與 DRF 的DefaultRouter
配合,自動生成 RESTful URL 模式。 - 自定義擴展:可通過重寫
perform_create
、get_queryset
等方法添加自定義邏輯。 - 序列化器與查詢集:
GenericAPIView
和GenericViewSet
需要明確指定queryset
和serializer_class
,否則需重寫對應方法。
代碼
以下是一個展示 Django REST Framework 中 mixins.CreateModelMixin
、mixins.ListModelMixin
、GenericAPIView
和 GenericViewSet
使用方式的代碼示例。代碼基于一個簡單的博客應用,包含模型、序列化器和視圖,涵蓋這些組件的主要方法和職責。
# models.py
from django.db import modelsclass Post(models.Model):title = models.CharField(max_length=100)content = models.TextField()created_at = models.DateTimeField(auto_now_add=True)def __str__(self):return self.title# serializers.py
from rest_framework import serializers
from .models import Postclass PostSerializer(serializers.ModelSerializer):class Meta:model = Postfields = ['id', 'title', 'content', 'created_at']# views.py
from rest_framework import mixins, generics, viewsets
from rest_framework.response import Response
from .models import Post
from .serializers import PostSerializer# 使用 GenericAPIView 結合 Mixins
class PostListCreateView(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):queryset = Post.objects.all()serializer_class = PostSerializerdef get(self, request, *args, **kwargs):# 調用 ListModelMixin 的 list 方法return self.list(request, *args, **kwargs)def post(self, request, *args, **kwargs):# 調用 CreateModelMixin 的 create 方法return self.create(request, *args, **kwargs)def perform_create(self, serializer):# 自定義 create 邏輯,例如添加當前用戶serializer.save() # 簡單保存,實際可添加 user=request.user# 使用 GenericViewSet 結合 Mixins
class PostViewSet(mixins.CreateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):queryset = Post.objects.all()serializer_class = PostSerializerdef perform_create(self, serializer):# 自定義 create 邏輯serializer.save() # 可擴展為保存額外字段# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import PostListCreateView, PostViewSet# 路由器用于 ViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)urlpatterns = [# GenericAPIView + Mixins 的路由path('posts/list-create/', PostListCreateView.as_view(), name='post-list-create'),# ViewSet 的路由path('', include(router.urls)),
]
代碼說明
-
模型和序列化器:
Post
模型定義了博客文章的基本字段。PostSerializer
用于序列化和反序列化Post
模型數據。
-
PostListCreateView(GenericAPIView + Mixins):
- 繼承
GenericAPIView
、ListModelMixin
和CreateModelMixin
。 get
方法調用list
方法(來自ListModelMixin
),處理 GET 請求,返回文章列表。post
方法調用create
方法(來自CreateModelMixin
),處理 POST 請求,創建新文章。- 重寫了
perform_create
方法,可添加自定義保存邏輯。
- 繼承
-
PostViewSet(GenericViewSet + Mixins):
- 繼承
GenericViewSet
、CreateModelMixin
和ListModelMixin
。 - 通過路由器自動生成
/posts/
(GET 列出)和/posts/
(POST 創建)的路由。 - 同樣支持
perform_create
自定義邏輯。
- 繼承
-
URL 配置:
PostListCreateView
使用手動定義的 URL 路由。PostViewSet
使用 DRF 的DefaultRouter
自動生成 RESTful 路由。
使用效果
- GET /posts/list-create/:返回所有文章列表(分頁由
GenericAPIView
的paginate_queryset
支持)。 - POST /posts/list-create/:創建新文章,返回 201 狀態碼和創建的文章數據。
- GET /posts/(ViewSet):列出文章。
- POST /posts/(ViewSet):創建新文章。
運行方式
- 確保 Django 和 DRF 已安裝:
pip install django djangorestframework
- 將代碼添加到 Django 項目中,配置好
models.py
、serializers.py
、views.py
和urls.py
。 - 運行遷移命令以創建數據庫表:
python manage.py makemigrations python manage.py migrate
- 啟動 Django 服務:
python manage.py runserver
擴展提示
- 添加權限:在視圖中設置
permission_classes
(如IsAuthenticated
)以限制訪問。 - 分頁:通過
DEFAULT_PAGINATION_CLASS
設置全局分頁,或在視圖中自定義pagination_class
。 - 過濾:使用
filter_backends
和django-filter
實現查詢集過濾。