【Django DRF】一篇文章總結Django DRF框架

第一章 DRF框架基礎

1.1 DRF簡介

1.1.1 DRF定義與作用
1. 定義

DRF 即 Django REST framework,它是一個建立在 Django 基礎之上的強大且靈活的工具包,用于構建 Web API(應用程序編程接口)😎。簡單來說,它就像是一個“橋梁”,幫助我們在 Django 項目中更輕松地創建和管理與外部應用或客戶端進行數據交互的接口。

2. 作用
  • 數據交互:允許不同的系統(如移動應用、前端網頁等)與 Django 后端進行數據的傳輸和交換。例如,一個移動應用可以通過調用 DRF 提供的 API 來獲取用戶的個人信息、發布新的動態等📱。
  • 簡化開發:提供了許多現成的工具和類,減少了開發人員編寫重復代碼的工作量。比如,它內置了序列化器(Serializer),可以方便地將 Django 模型(Model)中的數據轉換為適合在網絡上傳輸的格式(如 JSON),反之亦然。
1.1.2 DRF的優勢
  • 豐富的功能:DRF 提供了一系列強大的功能,如認證(Authentication)、權限控制(Permissions)、限流(Throttling)等。例如,通過設置不同的權限類,可以精確控制哪些用戶可以訪問哪些 API 接口,保障數據的安全性🔒。
  • 良好的文檔支持:擁有詳細且完善的官方文檔,即使是初學者也能快速上手。文檔中包含了大量的示例代碼和使用說明,方便開發人員參考和學習📚。
  • 高度可定制:可以根據項目的具體需求對 DRF 進行定制。例如,自定義序列化器的行為、編寫自己的認證類等,滿足不同場景下的開發要求。
  • 與 Django 集成良好:由于是基于 Django 開發的,DRF 可以很好地與 Django 的其他組件(如數據庫模型、視圖等)集成,充分利用 Django 的優勢,提高開發效率👍。

1.2 DRF安裝與環境配置

1.2.1 安裝DRF

要安裝 DRF,首先需要確保你已經安裝了 Python 和 Django。然后,使用 pip(Python 包管理工具)來安裝 DRF,在命令行中輸入以下命令:

pip install djangorestframework

安裝完成后,你可以通過以下命令來驗證是否安裝成功:

pip show djangorestframework

如果顯示了 DRF 的相關信息,說明安裝成功啦🎉。

1.2.2 配置Django項目以使用DRF

安裝好 DRF 后,還需要對 Django 項目進行一些配置。

1. 添加 rest_frameworkINSTALLED_APPS

打開 Django 項目的 settings.py 文件,在 INSTALLED_APPS 列表中添加 'rest_framework',如下所示:

INSTALLED_APPS = [# ...'rest_framework',# ...
]
2. 配置全局設置(可選)

你可以在 settings.py 文件中添加一些全局的 DRF 設置,例如設置默認的認證類和權限類:

REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.SessionAuthentication','rest_framework.authentication.BasicAuthentication'],'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated']
}

以上配置表示默認使用會話認證和基本認證,并且只有經過認證的用戶才能訪問 API 接口。

1.3 第一個DRF項目示例

1.3.1 創建項目與應用
1. 創建 Django 項目

打開命令行,進入你想要創建項目的目錄,然后執行以下命令創建一個新的 Django 項目:

django-admin startproject drf_example
cd drf_example
2. 創建 Django 應用

在項目目錄下,執行以下命令創建一個新的 Django 應用:

python manage.py startapp myapp
1.3.2 編寫簡單的視圖與序列化器
1. 定義模型

打開 myapp/models.py 文件,定義一個簡單的模型,例如:

from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=100)def __str__(self):return self.title
2. 創建序列化器

myapp 目錄下創建一個 serializers.py 文件,編寫一個序列化器來處理 Book 模型的數據:

from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author']
3. 編寫視圖

打開 myapp/views.py 文件,編寫一個簡單的視圖來處理 API 請求:

from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializerclass BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializer
4. 配置 URL

打開 drf_example/urls.py 文件,配置 URL 路由:

from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from myapp.views import BookViewSetrouter = DefaultRouter()
router.register(r'books', BookViewSet)urlpatterns = [path('admin/', admin.site.urls),path('api/', include(router.urls)),
]
1.3.3 運行項目并測試接口
1. 遷移數據庫

在命令行中執行以下命令來創建數據庫表:

python manage.py makemigrations
python manage.py migrate
2. 運行項目

執行以下命令啟動 Django 開發服務器:

python manage.py runserver
3. 測試接口

打開瀏覽器或使用工具(如 Postman)訪問 http://127.0.0.1:8000/api/books/,你應該能看到一個空的 JSON 列表(因為還沒有添加任何書籍數據)。你還可以通過 POST 請求向該接口添加新的書籍數據,通過 GET 請求獲取所有書籍數據,通過 PUT 或 PATCH 請求更新書籍數據,通過 DELETE 請求刪除書籍數據等。這樣,一個簡單的 DRF 項目就完成啦👏!

第二章 序列化器(Serializers)

2.1 序列化器概述

2.1.1 序列化與反序列化的概念

1. 序列化
  • 定義:序列化是將程序中的數據結構(如 Python 中的字典、列表、對象等)轉換為一種可以在網絡上傳輸或者存儲到文件中的格式(如 JSON、XML 等)的過程😃。就好比你要把家里的各種物品(數據結構)打包(序列化)成一個可以搬運(傳輸或存儲)的箱子。
  • 示例:在 Python 中,有一個包含用戶信息的字典 user = {'name': 'Alice', 'age': 25},將其轉換為 JSON 字符串 '{"name": "Alice", "age": 25}' 的過程就是序列化。
2. 反序列化
  • 定義:反序列化則是序列化的逆過程,它是將從網絡或文件中獲取的序列化后的數據(如 JSON 字符串)轉換回程序可以處理的數據結構(如 Python 中的字典、對象等)的過程🤔。這就像是把搬運來的箱子(序列化數據)打開,把里面的物品(數據結構)重新擺放到家里。
  • 示例:將 JSON 字符串 '{"name": "Alice", "age": 25}' 轉換為 Python 字典 {'name': 'Alice', 'age': 25} 的過程就是反序列化。

2.1.2 序列化器的作用

  • 數據轉換:序列化器可以方便地將復雜的數據結構轉換為適合傳輸或存儲的格式,以及將接收到的數據反序列化為程序可處理的數據結構。例如,在 Web 開發中,將數據庫中的模型對象轉換為 JSON 格式返回給前端,或者將前端傳來的 JSON 數據轉換為模型對象進行保存。
  • 數據驗證:在反序列化過程中,序列化器可以對輸入的數據進行驗證,確保數據的有效性和完整性。比如,驗證用戶輸入的年齡是否為正整數,郵箱格式是否正確等。
  • 數據篩選和展示:可以根據需要對數據進行篩選和處理,只返回客戶端需要的部分數據。例如,在返回用戶信息時,只返回用戶名和頭像,而不返回敏感的密碼信息。

2.2 基本序列化器使用

2.2.1 定義序列化器類

在 Django REST Framework 中,我們可以通過繼承 serializers.Serializer 類來定義自己的序列化器類。以下是一個簡單的示例:

from rest_framework import serializersclass UserSerializer(serializers.Serializer):name = serializers.CharField(max_length=100)age = serializers.IntegerField()

在這個示例中,我們定義了一個 UserSerializer 類,它包含兩個字段:nameage,分別使用 CharFieldIntegerField 進行定義。

2.2.2 序列化數據

序列化數據的過程就是將 Python 對象轉換為 JSON 等格式的過程。以下是一個序列化數據的示例:

from rest_framework import serializersclass UserSerializer(serializers.Serializer):name = serializers.CharField(max_length=100)age = serializers.IntegerField()user = {'name': 'Bob', 'age': 30}
serializer = UserSerializer(user)
print(serializer.data)  # 輸出: {'name': 'Bob', 'age': 30}

在這個示例中,我們創建了一個 UserSerializer 實例,并將一個包含用戶信息的字典傳遞給它。然后通過 serializer.data 獲取序列化后的數據。

2.2.3 反序列化數據

反序列化數據的過程就是將 JSON 等格式的數據轉換為 Python 對象的過程。以下是一個反序列化數據的示例:

from rest_framework import serializersclass UserSerializer(serializers.Serializer):name = serializers.CharField(max_length=100)age = serializers.IntegerField()data = {'name': 'Charlie', 'age': 35}
serializer = UserSerializer(data=data)
if serializer.is_valid():print(serializer.validated_data)  # 輸出: {'name': 'Charlie', 'age': 35}
else:print(serializer.errors)

在這個示例中,我們創建了一個 UserSerializer 實例,并將一個包含用戶信息的字典作為數據傳遞給它。然后調用 is_valid() 方法進行數據驗證,如果驗證通過,則可以通過 serializer.validated_data 獲取驗證后的數據。

2.3 模型序列化器(ModelSerializer)

2.3.1 模型序列化器的特點

  • 自動映射字段:模型序列化器可以根據模型類自動映射字段,無需手動定義每個字段,大大減少了代碼量。
  • 自動實現創建和更新方法:模型序列化器默認實現了 create()update() 方法,可以方便地進行數據的創建和更新操作。
  • 與模型緊密關聯:模型序列化器與模型類緊密關聯,可以直接對模型對象進行序列化和反序列化操作。

2.3.2 定義和使用模型序列化器

以下是一個定義和使用模型序列化器的示例:

from rest_framework import serializers
from .models import Userclass UserModelSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['name', 'age']user = User.objects.get(id=1)
serializer = UserModelSerializer(user)
print(serializer.data)

在這個示例中,我們定義了一個 UserModelSerializer 類,通過 Meta 類指定了關聯的模型類 User 和需要序列化的字段 ['name', 'age']。然后創建了一個 UserModelSerializer 實例,并將一個 User 模型對象傳遞給它,最后獲取序列化后的數據。

2.3.3 模型序列化器的高級用法

  • 嵌套序列化:可以在模型序列化器中嵌套使用其他序列化器,以處理關聯關系。例如,一個用戶可以有多個文章,我們可以在用戶序列化器中嵌套文章序列化器。
  • 自定義字段:可以通過自定義字段來實現一些特殊的序列化和反序列化邏輯。例如,將日期字段格式化為特定的字符串。
  • 額外的元數據:可以通過 Meta 類的其他屬性來指定一些額外的元數據,如 read_only_fieldswrite_only_fields 等。

2.4 序列化器的驗證

2.4.1 字段級驗證

字段級驗證是對單個字段進行驗證的方法。可以通過在序列化器類中定義以 validate_<field_name> 命名的方法來實現。以下是一個示例:

from rest_framework import serializersclass UserSerializer(serializers.Serializer):name = serializers.CharField(max_length=100)age = serializers.IntegerField()def validate_age(self, value):if value < 0:raise serializers.ValidationError("年齡不能為負數")return value

在這個示例中,我們定義了一個 validate_age 方法,用于驗證 age 字段的值是否為負數。如果是負數,則拋出 ValidationError 異常。

2.4.2 對象級驗證

對象級驗證是對整個對象進行驗證的方法。可以通過在序列化器類中定義 validate 方法來實現。以下是一個示例:

from rest_framework import serializersclass UserSerializer(serializers.Serializer):name = serializers.CharField(max_length=100)age = serializers.IntegerField()def validate(self, data):if data.get('name') == 'Admin' and data.get('age') < 18:raise serializers.ValidationError("管理員年齡必須大于等于 18 歲")return data

在這個示例中,我們定義了一個 validate 方法,用于驗證整個對象的數據。如果用戶名是 Admin 且年齡小于 18 歲,則拋出 ValidationError 異常。

2.4.3 自定義驗證器

除了字段級驗證和對象級驗證,還可以定義自定義驗證器,并將其應用到字段上。以下是一個示例:

from rest_framework import serializersdef validate_even(value):if value % 2 != 0:raise serializers.ValidationError("該字段必須為偶數")return valueclass NumberSerializer(serializers.Serializer):number = serializers.IntegerField(validators=[validate_even])

在這個示例中,我們定義了一個 validate_even 驗證器,用于驗證字段的值是否為偶數。然后將該驗證器應用到 NumberSerializer 類的 number 字段上。

第三章 視圖(Views)

在 Django REST framework(DRF)中,視圖是處理客戶端請求并返回響應的核心組件。視圖可以根據不同的需求和場景,采用不同的實現方式,下面我們將詳細介紹幾種常見的視圖類型。

3.1 基于函數的視圖(Function Based Views)

3.1.1 編寫簡單的基于函數的視圖

基于函數的視圖是最基本的視圖形式,它就是一個普通的 Python 函數,接收一個請求對象作為參數,并返回一個響應對象。以下是一個簡單的示例:

from django.http import JsonResponsedef simple_view(request):data = {'message': 'Hello, World!'}return JsonResponse(data)

在這個示例中,simple_view 函數接收一個 request 對象,然后創建一個包含消息的字典 data,最后使用 JsonResponse 返回一個 JSON 格式的響應。

3.1.2 使用 DRF 的裝飾器

DRF 提供了一些裝飾器來簡化基于函數的視圖的編寫。例如,@api_view 裝飾器可以用來指定視圖支持的 HTTP 請求方法。

from rest_framework.decorators import api_view
from rest_framework.response import Response@api_view(['GET'])
def get_view(request):data = {'message': 'This is a GET request.'}return Response(data)

在這個示例中,@api_view(['GET']) 裝飾器指定了該視圖只支持 GET 請求。如果客戶端發送其他類型的請求,DRF 會自動返回一個 405 Method Not Allowed 響應。

3.1.3 處理不同的 HTTP 請求方法

基于函數的視圖可以通過判斷 request.method 屬性來處理不同的 HTTP 請求方法。

from rest_framework.decorators import api_view
from rest_framework.response import Response@api_view(['GET', 'POST'])
def mixed_view(request):if request.method == 'GET':data = {'message': 'This is a GET request.'}elif request.method == 'POST':data = {'message': 'This is a POST request.'}return Response(data)

在這個示例中,mixed_view 視圖支持 GET 和 POST 請求。根據請求的方法不同,返回不同的響應數據。

3.2 基于類的視圖(Class Based Views)

3.2.1 基本的基于類的視圖

基于類的視圖是將視圖的邏輯封裝在類中,通過類的方法來處理不同的 HTTP 請求方法。以下是一個簡單的示例:

from django.http import JsonResponse
from django.views import Viewclass SimpleClassView(View):def get(self, request):data = {'message': 'This is a GET request from class view.'}return JsonResponse(data)

在這個示例中,SimpleClassView 類繼承自 View 類,并實現了 get 方法來處理 GET 請求。

3.2.2 繼承 APIView 類

DRF 提供了 APIView 類,它是基于類的視圖的基類,提供了更多的功能和靈活性。

from rest_framework.views import APIView
from rest_framework.response import Responseclass APIClassView(APIView):def get(self, request):data = {'message': 'This is a GET request from APIView.'}return Response(data)

在這個示例中,APIClassView 類繼承自 APIView 類,并實現了 get 方法。APIView 類會自動處理請求和響應的序列化和反序列化,以及權限驗證等功能。

3.2.3 類視圖的方法與屬性

類視圖有一些常用的方法和屬性:

  • 方法

    • get:處理 GET 請求。
    • post:處理 POST 請求。
    • put:處理 PUT 請求。
    • patch:處理 PATCH 請求。
    • delete:處理 DELETE 請求。
  • 屬性

    • request:當前的請求對象。
    • kwargs:URL 中的關鍵字參數。

3.3 通用視圖(Generic Views)

3.3.1 通用視圖的類型與用途

通用視圖是 DRF 提供的一組預定義的視圖,它們封裝了常見的視圖邏輯,如列表視圖、詳情視圖等。使用通用視圖可以減少代碼的重復,提高開發效率。

3.3.2 列表視圖與詳情視圖

列表視圖

列表視圖用于顯示一組對象的列表。以下是一個簡單的列表視圖示例:

from rest_framework.generics import ListAPIView
from .models import MyModel
from .serializers import MyModelSerializerclass MyModelListView(ListAPIView):queryset = MyModel.objects.all()serializer_class = MyModelSerializer

在這個示例中,MyModelListView 類繼承自 ListAPIView 類,并指定了查詢集和序列化器類。

詳情視圖

詳情視圖用于顯示單個對象的詳細信息。以下是一個簡單的詳情視圖示例:

from rest_framework.generics import RetrieveAPIView
from .models import MyModel
from .serializers import MyModelSerializerclass MyModelDetailView(RetrieveAPIView):queryset = MyModel.objects.all()serializer_class = MyModelSerializer

在這個示例中,MyModelDetailView 類繼承自 RetrieveAPIView 類,并指定了查詢集和序列化器類。

3.3.3 通用視圖的混合類(Mixins)

通用視圖是由多個混合類組合而成的。混合類是一些具有特定功能的類,可以通過繼承和組合來創建自定義的視圖。常見的混合類有:

  • ListModelMixin:提供列表視圖的功能。
  • CreateModelMixin:提供創建對象的功能。
  • RetrieveModelMixin:提供詳情視圖的功能。
  • UpdateModelMixin:提供更新對象的功能。
  • DestroyModelMixin:提供刪除對象的功能。

以下是一個使用混合類創建自定義視圖的示例:

from rest_framework.mixins import ListModelMixin, CreateModelMixin
from rest_framework.generics import GenericAPIView
from .models import MyModel
from .serializers import MyModelSerializerclass MyCustomView(ListModelMixin, CreateModelMixin, GenericAPIView):queryset = MyModel.objects.all()serializer_class = MyModelSerializerdef get(self, request, *args, **kwargs):return self.list(request, *args, **kwargs)def post(self, request, *args, **kwargs):return self.create(request, *args, **kwargs)

在這個示例中,MyCustomView 類繼承了 ListModelMixinCreateModelMixinGenericAPIView 類,并實現了 getpost 方法來處理 GET 和 POST 請求。

3.4 視圖集(ViewSets)

3.4.1 視圖集的概念與優勢

視圖集是一種將相關的視圖邏輯組合在一起的方式。它將不同的 HTTP 請求方法映射到不同的操作上,如列表、詳情、創建、更新、刪除等。使用視圖集可以進一步簡化代碼,提高開發效率。

3.4.2 基本視圖集的使用

以下是一個簡單的視圖集示例:

from rest_framework.viewsets import ModelViewSet
from .models import MyModel
from .serializers import MyModelSerializerclass MyModelViewSet(ModelViewSet):queryset = MyModel.objects.all()serializer_class = MyModelSerializer

在這個示例中,MyModelViewSet 類繼承自 ModelViewSet 類,并指定了查詢集和序列化器類。ModelViewSet 類提供了列表、詳情、創建、更新、刪除等操作的默認實現。

3.4.3 路由與視圖集的關聯

視圖集需要與路由進行關聯,才能將請求分發到相應的視圖方法上。DRF 提供了 DefaultRouter 來自動生成路由。

from rest_framework.routers import DefaultRouter
from .views import MyModelViewSetrouter = DefaultRouter()
router.register(r'mymodels', MyModelViewSet)urlpatterns = router.urls

在這個示例中,使用 DefaultRouter 注冊了 MyModelViewSet 視圖集,并指定了路由前綴為 mymodelsrouter.urls 會自動生成與視圖集對應的 URL 模式。

🎉 通過以上介紹,我們詳細了解了 DRF 中幾種常見的視圖類型,包括基于函數的視圖、基于類的視圖、通用視圖和視圖集。不同的視圖類型適用于不同的場景,可以根據實際需求選擇合適的視圖類型來開發 RESTful API。

第四章 路由(Routers)

4.1 路由概述

4.1.1 路由的作用

在 Web 開發中,路由就像是一位聰明的“交通指揮家”🚥,它的主要作用是將客戶端的請求(比如瀏覽器發出的請求)準確地引導到對應的視圖函數或視圖集上進行處理。

想象一下,一個 Web 應用就像是一座大型的商場🏬,里面有各種各樣的店鋪(視圖函數或視圖集),而路由就是商場里的指示牌,告訴顧客(客戶端請求)應該去哪個店鋪(視圖)。

具體來說,路由的作用包括:

  • 請求分發:根據請求的 URL 路徑,將請求轉發到合適的視圖進行處理。例如,當用戶訪問 http://example.com/products 時,路由會將這個請求導向處理產品列表的視圖。
  • URL 映射:將 URL 與視圖建立映射關系,使得開發者可以靈活地定義 URL 格式。比如,我們可以將 /products/<int:product_id> 映射到處理單個產品詳情的視圖。

4.1.2 DRF 中的路由機制

Django REST framework(DRF)提供了強大而靈活的路由機制,它可以幫助我們更高效地管理 API 的 URL 配置。

DRF 的路由機制主要基于 Django 的 URL 配置系統,并進行了擴展。它支持自動生成路由,減少了手動編寫 URL 配置的工作量。

DRF 提供了兩種主要的路由類:DefaultRouterSimpleRouter。這兩個路由類可以根據視圖集自動生成一系列的 URL 模式,例如列表視圖、詳情視圖、創建視圖等。

例如,對于一個 ProductViewSet 視圖集,使用 DRF 的路由機制可以自動生成 /products/(列表視圖)和 /products/<int:pk>/(詳情視圖)等 URL 模式。

4.2 簡單路由配置

4.2.1 手動配置路由

手動配置路由就像是自己一步一步地繪制商場的指示牌🖌?,雖然麻煩一些,但可以讓我們對 URL 配置有更精細的控制。

在 Django 中,我們可以使用 urlpatterns 列表來手動配置路由。例如:

from django.urls import path
from .views import ProductList, ProductDetailurlpatterns = [path('products/', ProductList.as_view(), name='product-list'),path('products/<int:pk>/', ProductDetail.as_view(), name='product-detail'),
]

在這個例子中,我們手動將 /products/ 映射到 ProductList 視圖,將 /products/<int:pk>/ 映射到 ProductDetail 視圖。

4.2.2 處理不同視圖的路由

在實際開發中,我們可能會有不同類型的視圖,如函數視圖和類視圖,需要根據不同的視圖類型進行路由配置。

函數視圖

函數視圖是最簡單的視圖類型,我們可以直接將函數名作為路由的處理函數。例如:

from django.urls import path
from .views import product_list, product_detailurlpatterns = [path('products/', product_list, name='product-list'),path('products/<int:product_id>/', product_detail, name='product-detail'),
]
類視圖

類視圖提供了更強大的功能和更好的代碼組織,我們需要使用 as_view() 方法將類視圖轉換為可調用的視圖函數。例如:

from django.urls import path
from .views import ProductListView, ProductDetailViewurlpatterns = [path('products/', ProductListView.as_view(), name='product-list'),path('products/<int:pk>/', ProductDetailView.as_view(), name='product-detail'),
]

4.3 自動路由生成

4.3.1 使用 DefaultRouter

DefaultRouter 是 DRF 提供的一個非常方便的路由類,它可以根據視圖集自動生成一系列的 URL 模式,并且還會自動生成一個 API 根視圖。

使用 DefaultRouter 的步驟如下:

  1. 導入 DefaultRouter 類:
from rest_framework.routers import DefaultRouter
  1. 創建 DefaultRouter 實例:
router = DefaultRouter()
  1. 注冊視圖集:
from .views import ProductViewSetrouter.register(r'products', ProductViewSet)
  1. 獲取 URL 模式:
urlpatterns = router.urls

這樣,DefaultRouter 會自動生成 /products/(列表視圖)、/products/<int:pk>/(詳情視圖)等 URL 模式,還會生成一個 API 根視圖,方便我們查看 API 的整體結構。

4.3.2 使用 SimpleRouter

SimpleRouterDefaultRouter 類似,也可以根據視圖集自動生成 URL 模式,但它不會生成 API 根視圖。

使用 SimpleRouter 的步驟與 DefaultRouter 基本相同:

  1. 導入 SimpleRouter 類:
from rest_framework.routers import SimpleRouter
  1. 創建 SimpleRouter 實例:
router = SimpleRouter()
  1. 注冊視圖集:
from .views import ProductViewSetrouter.register(r'products', ProductViewSet)
  1. 獲取 URL 模式:
urlpatterns = router.urls

4.3.3 自定義路由

有時候,自動生成的路由可能無法滿足我們的需求,這時候就需要進行自定義路由。

我們可以繼承 DefaultRouterSimpleRouter 類,并重寫一些方法來實現自定義路由。例如,我們可以自定義 URL 模式的生成規則。

from rest_framework.routers import DefaultRouterclass CustomRouter(DefaultRouter):def get_urls(self):urls = super().get_urls()# 在這里可以添加自定義的 URL 模式custom_urls = [# 自定義 URL 模式]urls.extend(custom_urls)return urlsrouter = CustomRouter()
router.register(r'products', ProductViewSet)
urlpatterns = router.urls

通過自定義路由,我們可以根據具體的業務需求靈活地調整 URL 配置。🎉

第五章 認證與權限(Authentication and Permissions)

5.1 認證機制

5.1.1 認證的概念與作用

1. 概念

認證(Authentication)是指系統對用戶身份進行驗證的過程,就像你進入一個高級俱樂部,門口的保安會檢查你的會員卡來確認你是否有進入的資格😃。在軟件開發中,認證就是要確定訪問系統的用戶到底是誰,確保只有合法的用戶能夠訪問系統資源。

2. 作用
  • 保護數據安全:只有經過認證的用戶才能訪問敏感數據,防止數據泄露。例如,銀行系統只有認證通過的用戶才能查看賬戶余額和交易記錄,避免他人隨意獲取這些重要信息💰。
  • 提供個性化服務:根據不同用戶的身份,系統可以提供不同的服務。比如電商平臺,認證后的用戶可以看到自己的購物車、歷史訂單等個性化內容🛒。
  • 控制訪問權限:為后續的權限控制提供基礎,只有先確認了用戶身份,才能進一步判斷該用戶是否有權限進行某些操作。

5.1.2 DRF內置的認證類

Django REST framework(DRF)提供了一些內置的認證類,方便開發者快速實現認證功能。

1. SessionAuthentication
  • 原理:基于 Django 的會話機制,用戶登錄后,服務器會在客戶端瀏覽器中設置一個會話 ID,后續的請求中會攜帶這個會話 ID,服務器通過驗證會話 ID 來確認用戶身份。就像你進入一個商場,商場給你一張會員卡,你每次進入商場都要出示這張卡,商場通過卡上的信息確認你是會員😉。
  • 使用場景:適用于前后端不分離的項目,用戶通過瀏覽器進行登錄和操作。
2. BasicAuthentication
  • 原理:客戶端在請求頭中攜帶用戶名和密碼的 Base64 編碼,服務器對其進行解碼和驗證。就像你去一個小店鋪,老板讓你報上自己的名字和密碼來證明身份🧐。
  • 使用場景:簡單的測試環境或者對安全性要求不高的場景。
3. TokenAuthentication
  • 原理:用戶登錄成功后,服務器會生成一個唯一的令牌(Token),并返回給客戶端。客戶端在后續的請求中攜帶這個令牌,服務器通過驗證令牌來確認用戶身份。就像你去參加一個活動,活動方給你一個入場券,你憑這個入場券進入活動現場🎫。
  • 使用場景:適用于前后端分離的項目,客戶端可以是移動應用或者其他第三方應用。

5.1.3 自定義認證類

有時候,DRF 內置的認證類可能無法滿足項目的特殊需求,這時候就需要自定義認證類。

1. 自定義步驟
  • 繼承 BaseAuthentication 類:從 DRF 的 BaseAuthentication 類繼承,創建自己的認證類。
  • 重寫 authenticate 方法:在 authenticate 方法中實現具體的認證邏輯。例如,驗證用戶的自定義令牌或者使用第三方認證服務。
2. 示例代碼
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from myapp.models import MyUserclass CustomAuthentication(BaseAuthentication):def authenticate(self, request):# 從請求頭中獲取自定義的認證信息auth_header = request.headers.get('X-Custom-Auth')if not auth_header:return None  # 沒有提供認證信息,返回 Nonetry:# 驗證認證信息,這里假設是用戶 IDuser_id = int(auth_header)user = MyUser.objects.get(id=user_id)except (ValueError, MyUser.DoesNotExist):raise AuthenticationFailed('Invalid authentication credentials.')return (user, None)  # 返回認證成功的用戶和 None

5.2 權限控制

5.2.1 權限的概念與作用

1. 概念

權限(Permissions)是指系統對用戶訪問資源和執行操作的限制。即使一個用戶通過了認證,也不意味著他可以隨意訪問系統的所有資源和執行所有操作。就像在一個公司里,不同職位的員工有不同的權限,普通員工只能訪問自己的工作區域和相關文件,而經理可能有更高的權限可以訪問更多的資源📁。

2. 作用
  • 數據隔離:不同用戶只能訪問自己有權限的數據,保護數據的隱私和安全。例如,在一個多租戶的系統中,每個租戶只能訪問自己的數據,不能訪問其他租戶的數據。
  • 操作限制:限制用戶只能執行自己有權限的操作,防止誤操作或者惡意操作。比如,普通用戶只能查看文章,而管理員可以編輯和刪除文章。

5.2.2 DRF內置的權限類

DRF 提供了一些內置的權限類,方便開發者實現權限控制。

1. AllowAny
  • 作用:允許任何用戶訪問,不進行任何權限驗證。就像一個公共公園,任何人都可以自由進入🌳。
  • 使用場景:適用于不需要進行權限控制的接口,如公共信息的獲取接口。
2. IsAuthenticated
  • 作用:只允許經過認證的用戶訪問。就像一個會員制的健身房,只有會員才能進入鍛煉🏋?。
  • 使用場景:適用于需要用戶登錄才能訪問的接口,如用戶個人信息的獲取接口。
3. IsAdminUser
  • 作用:只允許管理員用戶訪問。就像公司的機密會議室,只有管理層才能進入開會👨?💼。
  • 使用場景:適用于只有管理員才能執行的操作,如系統設置的修改接口。

5.2.3 自定義權限類

同樣,當 DRF 內置的權限類無法滿足需求時,我們可以自定義權限類。

1. 自定義步驟
  • 繼承 BasePermission 類:從 DRF 的 BasePermission 類繼承,創建自己的權限類。
  • 重寫 has_permission 方法:在 has_permission 方法中實現具體的權限驗證邏輯。
2. 示例代碼
from rest_framework.permissions import BasePermissionclass CustomPermission(BasePermission):def has_permission(self, request, view):# 假設只有用戶名為 'special_user' 的用戶才有訪問權限if request.user.username == 'special_user':return Truereturn False

5.3 認證與權限的應用

5.3.1 在視圖中配置認證與權限

在 DRF 中,可以在視圖類中單獨配置認證和權限。

示例代碼
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticatedclass MyView(APIView):authentication_classes = [TokenAuthentication]permission_classes = [IsAuthenticated]def get(self, request):return Response({'message': 'Hello, authenticated user!'})

在這個示例中,MyView 視圖使用 TokenAuthentication 進行認證,只有經過認證的用戶才能訪問該視圖,并且使用 IsAuthenticated 權限類確保只有認證用戶才能執行該視圖的操作。

5.3.2 全局配置認證與權限

除了在視圖中單獨配置,還可以在項目的 settings.py 文件中進行全局配置。

示例代碼
REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication',],'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated',]
}

這樣配置后,所有的視圖都會默認使用 TokenAuthentication 進行認證,并且只有經過認證的用戶才能訪問。如果某個視圖需要特殊的認證或權限配置,可以在視圖類中單獨覆蓋默認配置。

通過以上的認證和權限配置,可以確保系統的安全性和數據的完整性,讓不同的用戶只能訪問和操作他們有權限的資源和功能👍。

第六章 節流(Throttling)

6.1 節流概述

6.1.1 節流的作用

節流是一種在軟件開發中常用的優化技術,它的主要作用就像是給水龍頭安裝了一個限流裝置🚰,讓水流(請求)按照一定的速率流出,而不是一股腦地全部涌出來。

在實際的應用場景中,當用戶頻繁觸發某個操作時,例如頻繁點擊按鈕、快速滾動頁面觸發的事件等,如果不加以限制,可能會導致服務器壓力過大,出現性能問題,甚至崩潰。節流通過限制某個函數在一定時間內的執行次數,避免了這種過度請求的情況,使得系統能夠更加穩定、高效地運行。

比如,在一個電商網站的搜索框中,用戶可能會快速輸入關鍵詞進行搜索。如果每輸入一個字符就立即向服務器發送一次搜索請求,服務器會不堪重負。使用節流技術后,我們可以設置在用戶輸入停止一段時間后再發送請求,這樣既保證了用戶的搜索體驗,又減輕了服務器的壓力。

6.1.2 節流的應用場景

節流在很多場景中都有廣泛的應用,以下是一些常見的例子:

  • 按鈕點擊事件:在一些需要提交表單或者執行重要操作的按鈕上,為了防止用戶誤操作或者惡意快速點擊,我們可以使用節流。例如,在一個注冊按鈕上,使用節流后,用戶點擊按鈕后,在一定時間內再次點擊將不會觸發注冊請求,避免重復提交表單。

  • 滾動加載:當我們瀏覽網頁時,經常會遇到滾動頁面加載更多內容的情況。如果不使用節流,用戶快速滾動頁面時,會觸發大量的加載請求,導致頁面卡頓。通過節流,我們可以限制在一定時間內只觸發一次加載請求,提高頁面的性能和用戶體驗。

  • 窗口大小改變事件:當用戶調整瀏覽器窗口大小時,會觸發 resize 事件。如果在這個事件中執行一些復雜的計算或者重新布局的操作,頻繁觸發會導致性能問題。使用節流可以限制事件的觸發頻率,減少不必要的計算。

6.2 DRF內置節流類

6.2.1 AnonRateThrottle

AnonRateThrottle 是 Django REST framework(DRF)中用于限制匿名用戶請求速率的節流類。它就像是一個“門衛”,專門對沒有登錄的用戶進行流量控制🚪。

這個節流類會根據配置的速率限制匿名用戶的請求次數。例如,我們可以配置為每分鐘允許匿名用戶發送 10 次請求。如果匿名用戶在一分鐘內發送的請求超過了這個數量,后續的請求將會被拒絕,服務器會返回一個 429 Too Many Requests 錯誤。

以下是一個簡單的配置示例:

REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle',],'DEFAULT_THROTTLE_RATES': {'anon': '10/min',  # 每分鐘允許 10 次請求}
}

6.2.2 UserRateThrottle

UserRateThrottle 是用于限制已登錄用戶請求速率的節流類。與 AnonRateThrottle 不同,它針對的是已經通過身份驗證的用戶。

同樣,我們可以根據需要配置已登錄用戶的請求速率。例如,我們可以設置為每小時允許每個用戶發送 100 次請求。這樣可以防止個別用戶過度使用系統資源,保證系統的公平性和穩定性。

配置示例如下:

REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.UserRateThrottle',],'DEFAULT_THROTTLE_RATES': {'user': '100/hour',  # 每小時允許 100 次請求}
}

6.2.3 ScopedRateThrottle

ScopedRateThrottle 是一個更靈活的節流類,它允許我們根據不同的視圖或者操作范圍來設置不同的請求速率。就像是為不同的房間設置了不同的門禁規則🏠。

例如,我們可以為某個特定的 API 視圖設置一個較高的請求速率,而對其他視圖設置較低的速率。這樣可以根據不同的業務需求進行精細的流量控制。

以下是一個使用 ScopedRateThrottle 的示例:

from rest_framework.throttling import ScopedRateThrottle
from rest_framework.views import APIView
from rest_framework.response import Responseclass MyView(APIView):throttle_scope = 'my_scope'  # 定義節流范圍def get(self, request):return Response({'message': 'Hello, World!'})REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.ScopedRateThrottle',],'DEFAULT_THROTTLE_RATES': {'my_scope': '20/min',  # 每分鐘允許 20 次請求}
}

6.3 自定義節流類

6.3.1 自定義節流邏輯

有時候,DRF 提供的內置節流類可能無法滿足我們的特定需求,這時候就需要自定義節流類。自定義節流類就像是我們自己打造一個個性化的“流量控制器”🎛?。

要自定義節流類,我們需要繼承 rest_framework.throttling.BaseThrottle 類,并實現 allow_request 方法。allow_request 方法用于判斷當前請求是否允許通過,如果允許則返回 True,否則返回 False

以下是一個簡單的自定義節流類示例,該類限制每個用戶在 5 秒內只能發送一次請求:

from rest_framework.throttling import BaseThrottle
import timeclass CustomThrottle(BaseThrottle):def __init__(self):self.history = {}def allow_request(self, request, view):user = request.usernow = time.time()if user in self.history:last_request_time = self.history[user]if now - last_request_time < 5:  # 5 秒內只允許一次請求return Falseself.history[user] = nowreturn True

6.3.2 在視圖中應用自定義節流類

自定義好節流類后,我們需要在視圖中應用它。在 DRF 中,我們可以通過在視圖類中設置 throttle_classes 屬性來指定使用的節流類。

以下是一個在視圖中應用自定義節流類的示例:

from rest_framework.views import APIView
from rest_framework.response import Response
from .throttles import CustomThrottle  # 導入自定義節流類class MyCustomView(APIView):throttle_classes = [CustomThrottle]  # 應用自定義節流類def get(self, request):return Response({'message': 'This is a custom view with custom throttling.'})

這樣,當用戶訪問 MyCustomView 時,就會受到自定義節流類的限制。🎉

第七章 分頁(Pagination)

7.1 分頁的概念與作用

7.1.1 為什么需要分頁

在數據處理和展示的過程中,當數據量非常大時,如果一次性將所有數據都展示給用戶,會帶來很多問題😫:

  • 性能問題:加載大量數據會占用大量的網絡帶寬和服務器資源,導致頁面加載速度變慢。比如一個電商網站的商品列表,如果有上百萬條商品數據,一次性加載會讓服務器不堪重負,用戶可能需要等待很長時間才能看到頁面內容。
  • 用戶體驗問題:大量數據堆積在一起,會讓頁面變得混亂,用戶很難快速找到自己需要的信息。想象一下,打開一個新聞網站,所有的新聞都顯示在一個頁面上,密密麻麻的,根本無從下手。

分頁就是為了解決這些問題而出現的。它將大量的數據分成若干個小的“頁面”,每次只加載和展示其中的一個頁面,這樣既減輕了服務器的負擔,又提高了用戶體驗👍。

7.1.2 分頁的應用場景

分頁在很多場景中都有廣泛的應用:

  • 網站列表頁面:如新聞網站的新聞列表、電商網站的商品列表、招聘網站的職位列表等。用戶可以通過點擊頁碼或者“上一頁”“下一頁”按鈕來瀏覽不同頁面的內容。
  • 搜索結果頁面:當用戶進行搜索時,搜索結果可能有很多條,通過分頁可以讓用戶逐步查看。例如在搜索引擎中輸入關鍵詞,搜索結果會分頁展示,用戶可以根據自己的需求查看不同頁面的結果。
  • 數據管理系統:在企業的后臺管理系統中,對員工信息、訂單信息等數據進行管理時,也會用到分頁功能。管理員可以方便地查看和處理不同頁面的數據。

7.2 DRF 內置分頁類

7.2.1 PageNumberPagination

PageNumberPagination 是 DRF 中最常用的分頁類之一,它基于頁碼來進行分頁。用戶可以通過指定頁碼來獲取相應頁面的數據。

特點
  • 簡單直觀:用戶只需要知道頁碼就可以獲取對應頁面的數據,易于理解和使用。
  • 支持自定義:可以通過設置 page_size(每頁顯示的數據數量)、page_query_param(頁碼參數名)等屬性來定制分頁行為。
示例代碼
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Responseclass CustomPageNumberPagination(PageNumberPagination):page_size = 10  # 每頁顯示 10 條數據page_size_query_param = 'page_size'  # 允許用戶通過參數指定每頁顯示的數據數量max_page_size = 100  # 每頁最大顯示的數據數量def get_paginated_response(self, data):return Response({'links': {'next': self.get_next_link(),'previous': self.get_previous_link()},'count': self.page.paginator.count,'results': data})

7.2.2 LimitOffsetPagination

LimitOffsetPagination 基于偏移量和限制數量來進行分頁。limit 表示每頁顯示的數據數量,offset 表示從第幾條數據開始顯示。

特點
  • 靈活控制:用戶可以根據需要靈活指定從哪里開始顯示數據以及顯示多少條數據。
  • 適合特定場景:在需要跳過一定數量的數據或者獲取特定范圍的數據時非常有用。
示例代碼
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.response import Responseclass CustomLimitOffsetPagination(LimitOffsetPagination):default_limit = 10  # 默認每頁顯示 10 條數據limit_query_param = 'limit'  # 限制數量的參數名offset_query_param = 'offset'  # 偏移量的參數名max_limit = 100  # 最大限制數量def get_paginated_response(self, data):return Response({'links': {'next': self.get_next_link(),'previous': self.get_previous_link()},'count': self.count,'results': data})

7.2.3 CursorPagination

CursorPagination 是一種基于游標(cursor)的分頁方式,它通過一個不透明的游標來定位數據,而不是使用頁碼或偏移量。

特點
  • 安全性高:游標是一個不透明的字符串,不包含具體的頁碼或偏移量信息,避免了用戶通過修改參數來獲取非法數據。
  • 性能優化:在處理大量數據時,CursorPagination 可以提高性能,因為它不需要計算總頁數。
示例代碼
from rest_framework.pagination import CursorPagination
from rest_framework.response import Responseclass CustomCursorPagination(CursorPagination):page_size = 10  # 每頁顯示 10 條數據ordering = '-created_at'  # 按照創建時間降序排列cursor_query_param = 'cursor'  # 游標的參數名def get_paginated_response(self, data):return Response({'links': {'next': self.get_next_link(),'previous': self.get_previous_link()},'results': data})

7.3 自定義分頁類

7.3.1 自定義分頁邏輯

有時候,DRF 內置的分頁類可能無法滿足我們的需求,這時候就需要自定義分頁類。自定義分頁類需要繼承自 rest_framework.pagination.BasePagination 類,并實現 paginate_querysetget_paginated_response 方法。

示例代碼
from rest_framework.pagination import BasePagination
from rest_framework.response import Responseclass CustomPagination(BasePagination):page_size = 15  # 每頁顯示 15 條數據def paginate_queryset(self, queryset, request, view=None):page = int(request.query_params.get('page', 1))start = (page - 1) * self.page_sizeend = start + self.page_sizereturn list(queryset[start:end])def get_paginated_response(self, data):return Response({'results': data})

7.3.2 在視圖中應用自定義分頁類

在視圖中應用自定義分頁類非常簡單,只需要在視圖類中指定 pagination_class 屬性為自定義的分頁類即可。

示例代碼
from rest_framework.viewsets import ModelViewSet
from .models import MyModel
from .serializers import MyModelSerializer
from .pagination import CustomPaginationclass MyModelViewSet(ModelViewSet):queryset = MyModel.objects.all()serializer_class = MyModelSerializerpagination_class = CustomPagination

這樣,在訪問 MyModelViewSet 對應的接口時,就會使用自定義的分頁邏輯進行分頁啦👏。

第八章 過濾與排序(Filtering and Ordering)

在處理數據時,過濾和排序是非常重要的操作,它們可以幫助我們更高效地獲取和展示所需的數據。在 Django REST framework (DRF) 中,提供了強大的過濾和排序機制,下面我們來詳細了解一下。

8.1 過濾機制

過濾機制允許我們根據特定的條件篩選出符合要求的數據,就像是從一堆物品中挑選出我們需要的部分😃。

8.1.1 過濾的作用

過濾的主要作用是從大量的數據中篩選出我們需要的子集,提高數據的查詢效率和精準度。例如,在一個電商網站中,我們可能只想查看價格在某個范圍內的商品,或者只查看某個品牌的商品。通過過濾,我們可以快速地找到滿足這些條件的商品,而不需要遍歷整個商品列表。

  • 提高查詢效率:減少不必要的數據查詢,節省服務器資源和響應時間。
  • 精準定位數據:幫助用戶快速找到他們感興趣的數據。
8.1.2 DRF內置過濾后端

DRF 提供了幾種內置的過濾后端,方便我們快速實現過濾功能。

  • DjangoFilterBackend:這是一個非常常用的過濾后端,它基于 Django 的 django-filter 庫。我們可以通過定義過濾字段,讓用戶可以根據這些字段進行過濾。例如:
from rest_framework import generics
from django_filters.rest_framework import DjangoFilterBackend
from .models import Product
from .serializers import ProductSerializerclass ProductList(generics.ListAPIView):queryset = Product.objects.all()serializer_class = ProductSerializerfilter_backends = [DjangoFilterBackend]filterset_fields = ['price', 'brand']

在這個例子中,用戶可以通過在 URL 中添加 ?price=100&brand=Apple 這樣的參數來過濾商品。

  • SearchFilter:用于簡單的搜索過濾。我們可以指定搜索的字段,用戶可以通過在 URL 中添加 ?search=keyword 來搜索包含該關鍵詞的數據。例如:
from rest_framework import generics
from rest_framework.filters import SearchFilter
from .models import Product
from .serializers import ProductSerializerclass ProductList(generics.ListAPIView):queryset = Product.objects.all()serializer_class = ProductSerializerfilter_backends = [SearchFilter]search_fields = ['name', 'description']
  • OrderingFilter:雖然它主要用于排序,但也可以和其他過濾后端一起使用。我們可以指定可排序的字段,用戶可以通過在 URL 中添加 ?ordering=field_name 來對數據進行排序。
8.1.3 自定義過濾后端

有時候,內置的過濾后端可能無法滿足我們的需求,這時候就需要自定義過濾后端。自定義過濾后端需要繼承 BaseFilterBackend 類,并實現 filter_queryset 方法。例如:

from rest_framework.filters import BaseFilterBackend
from .models import Productclass CustomFilterBackend(BaseFilterBackend):def filter_queryset(self, request, queryset, view):# 自定義過濾邏輯min_price = request.query_params.get('min_price')if min_price is not None:queryset = queryset.filter(price__gte=min_price)return queryset

然后在視圖中使用自定義過濾后端:

from rest_framework import generics
from .models import Product
from .serializers import ProductSerializer
from .filters import CustomFilterBackendclass ProductList(generics.ListAPIView):queryset = Product.objects.all()serializer_class = ProductSerializerfilter_backends = [CustomFilterBackend]

8.2 排序機制

排序機制允許我們按照特定的規則對數據進行排序,就像是給物品按照大小、顏色等規則進行排列一樣😎。

8.2.1 排序的作用

排序的主要作用是讓數據按照我們期望的順序展示,方便用戶查看和比較。例如,在一個商品列表中,我們可以按照價格從低到高或者從高到低進行排序,讓用戶可以快速找到價格合適的商品。

  • 提高數據可讀性:讓數據更有組織性,方便用戶查看。
  • 便于數據比較:用戶可以更容易地比較不同數據項的大小、優劣等。
8.2.2 在視圖中實現排序

在 DRF 中,我們可以使用 OrderingFilter 來實現排序功能。首先,在視圖中添加 OrderingFilterfilter_backends 中,并指定可排序的字段。例如:

from rest_framework import generics
from rest_framework.filters import OrderingFilter
from .models import Product
from .serializers import ProductSerializerclass ProductList(generics.ListAPIView):queryset = Product.objects.all()serializer_class = ProductSerializerfilter_backends = [OrderingFilter]ordering_fields = ['price', 'created_at']ordering = ['-created_at']  # 默認按照創建時間降序排列

用戶可以通過在 URL 中添加 ?ordering=price 來按照價格升序排列,或者添加 ?ordering=-price 來按照價格降序排列。

8.2.3 自定義排序邏輯

如果內置的排序功能無法滿足我們的需求,我們也可以自定義排序邏輯。和自定義過濾后端類似,我們可以在視圖中重寫 get_queryset 方法來實現自定義排序。例如:

from rest_framework import generics
from .models import Product
from .serializers import ProductSerializerclass ProductList(generics.ListAPIView):queryset = Product.objects.all()serializer_class = ProductSerializerdef get_queryset(self):queryset = super().get_queryset()# 自定義排序邏輯sort_by = self.request.query_params.get('sort_by')if sort_by == 'custom':# 自定義排序規則queryset = sorted(queryset, key=lambda x: x.custom_score)return queryset

在這個例子中,用戶可以通過在 URL 中添加 ?sort_by=custom 來使用自定義的排序規則。

通過過濾和排序機制,我們可以讓數據的查詢和展示更加靈活和高效,為用戶提供更好的體驗😃。

第九章 版本控制(Versioning)

9.1 版本控制概述

9.1.1 版本控制的作用

在軟件開發的過程中,版本控制就像是一位“時間管理員”?,它有著至關重要的作用:

  • 記錄歷史變更:版本控制可以詳細記錄代碼每一次的修改情況,就像給代碼的每一次變化都拍了一張“快照”。這樣,開發人員可以隨時查看代碼在不同時間點的狀態,了解代碼是如何一步步演變的。例如,在一個大型項目中,經過幾個月的開發后,突然發現某個功能出現了問題,通過版本控制可以快速回溯到之前正常的版本,找出是從哪個版本開始出現問題的。
  • 支持團隊協作:在多人團隊開發中,不同的開發人員可能會同時對代碼進行修改。版本控制可以有效地管理這些并發的修改,避免沖突的發生。當多個開發人員對同一文件進行修改時,版本控制系統會提示沖突,并幫助開發人員合并這些修改,確保代碼的一致性。就好比一個樂隊演奏,每個樂手都有自己的部分,版本控制就是指揮,讓大家的演奏和諧統一。
  • 方便回滾操作:如果在開發過程中引入了新的功能,但這個功能導致了一些嚴重的問題,通過版本控制可以輕松地將代碼回滾到之前穩定的版本。這就像是在游戲中,如果玩家走錯了路,可以隨時回到上一個存檔點重新開始。
  • 促進代碼審查:版本控制可以清晰地顯示代碼的修改內容,方便團隊成員進行代碼審查。審查人員可以查看每個提交的詳細信息,了解修改的目的和影響,從而提出有針對性的建議和意見,提高代碼的質量。

9.1.2 版本控制的應用場景

版本控制在很多場景下都有著廣泛的應用:

  • 軟件開發項目:無論是小型的個人項目還是大型的企業級項目,版本控制都是必不可少的。在軟件開發過程中,代碼會不斷地進行修改和更新,版本控制可以幫助開發團隊更好地管理代碼,提高開發效率。例如,一個互聯網公司開發一款電商平臺,從項目的初始階段到不斷迭代升級,都需要使用版本控制來管理代碼。
  • 文檔管理:對于一些需要多人協作編輯的文檔,如技術文檔、項目報告等,版本控制也非常有用。它可以記錄文檔的每一次修改,方便查看歷史版本,同時也可以避免因誤操作導致的文檔丟失或錯誤。比如一個團隊共同編寫一份產品說明書,不同成員可以同時對文檔進行修改,通過版本控制可以確保文檔的完整性和準確性。
  • 開源項目:在開源社區中,版本控制是項目發展的基石。全球各地的開發者可以通過版本控制系統參與到項目的開發中,提交自己的代碼修改。例如,著名的開源項目 Linux 內核,就是通過版本控制來管理全球開發者的貢獻,使得項目能夠不斷發展壯大。

9.2 DRF 內置版本控制方案

9.2.1 URLPathVersioning

URLPathVersioning 是 DRF(Django REST Framework)中一種基于 URL 路徑的版本控制方案。在這種方案中,版本信息會直接包含在 URL 的路徑中。

例如,我們可以定義如下的 URL 格式:

# urls.py
from django.urls import path
from rest_framework.routers import DefaultRouter
from myapp.views import MyViewSetrouter = DefaultRouter()
router.register(r'v1/myresource', MyViewSet, basename='myresource')
router.register(r'v2/myresource', MyViewSet, basename='myresource')urlpatterns = [path('', include(router.urls)),
]

在這個例子中,v1v2 就是版本信息。當客戶端請求 http://example.com/v1/myresource/ 時,會使用版本 1 的接口;當請求 http://example.com/v2/myresource/ 時,會使用版本 2 的接口。

這種方案的優點是簡單直觀,版本信息一目了然,開發人員和客戶端都很容易理解。缺點是會使 URL 變得冗長,并且如果版本更新頻繁,需要不斷修改 URL 配置。

9.2.2 QueryParameterVersioning

QueryParameterVersioning 是通過 URL 的查詢參數來指定版本的。客戶端在請求時,通過在 URL 中添加版本參數來指定使用的版本。

例如,客戶端可以這樣請求:

http://example.com/myresource/?version=v1

在 DRF 中,我們可以這樣配置:

# settings.py
REST_FRAMEWORK = {'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.QueryParameterVersioning','DEFAULT_VERSION': 'v1','ALLOWED_VERSIONS': ['v1', 'v2'],'VERSION_PARAM': 'version'
}

在這個配置中,VERSION_PARAM 指定了查詢參數的名稱,DEFAULT_VERSION 指定了默認版本,ALLOWED_VERSIONS 指定了允許的版本列表。

這種方案的優點是靈活性高,不需要修改 URL 的路徑,只需要在查詢參數中指定版本即可。缺點是不夠直觀,客戶端需要在每次請求時都帶上版本參數。

9.2.3 AcceptHeaderVersioning

AcceptHeaderVersioning 是通過 HTTP 請求頭中的 Accept 字段來指定版本的。客戶端在請求時,通過在 Accept 字段中添加版本信息來指定使用的版本。

例如,客戶端可以這樣發送請求:

Accept: application/json; version=v1

在 DRF 中,我們可以這樣配置:

# settings.py
REST_FRAMEWORK = {'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning','DEFAULT_VERSION': 'v1','ALLOWED_VERSIONS': ['v1', 'v2'],'VERSION_PARAM': 'version'
}

這種方案的優點是不會影響 URL 的結構,使 URL 更加簡潔。缺點是對客戶端的要求較高,客戶端需要正確設置 Accept 頭。

9.3 自定義版本控制方案

9.3.1 自定義版本控制邏輯

有時候,DRF 內置的版本控制方案可能無法滿足我們的需求,這時候就需要自定義版本控制邏輯。

下面是一個簡單的自定義版本控制類的示例:

from rest_framework.versioning import BaseVersioning
from rest_framework.exceptions import APIExceptionclass CustomVersioning(BaseVersioning):def determine_version(self, request, *args, **kwargs):# 從請求頭中獲取版本信息version = request.headers.get('X-Custom-Version')if not version:# 如果沒有提供版本信息,拋出異常raise APIException('Version information is missing in the request headers.')if version not in ['v1', 'v2']:# 如果版本信息不在允許的列表中,拋出異常raise APIException('Invalid version number.')return version

在這個示例中,我們自定義了一個版本控制類 CustomVersioning,它從請求頭的 X-Custom-Version 字段中獲取版本信息,并進行合法性檢查。

9.3.2 在項目中應用自定義版本控制

要在項目中應用自定義版本控制,我們需要在 settings.py 中進行配置:

# settings.py
REST_FRAMEWORK = {'DEFAULT_VERSIONING_CLASS': 'myapp.versioning.CustomVersioning','DEFAULT_VERSION': 'v1','ALLOWED_VERSIONS': ['v1', 'v2'],'VERSION_PARAM': 'version'
}

同時,在視圖中也可以指定使用的版本控制類:

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from myapp.versioning import CustomVersioningclass MyView(APIView):versioning_class = CustomVersioningdef get(self, request, *args, **kwargs):version = request.versionreturn Response({'version': version})

通過這樣的配置,我們就可以在項目中使用自定義的版本控制方案了。🎉

第十章 測試(Testing)

10.1 DRF 測試概述

10.1.1 測試的重要性

在軟件開發的世界里,測試就像是一位嚴謹的“質量檢查員”🧐,它對于使用 Django REST Framework(DRF)構建的項目來說至關重要。

  • 發現缺陷:在開發過程中,代碼里難免會存在各種隱藏的錯誤和漏洞。通過測試,我們可以在項目上線之前就把這些問題找出來并解決掉,避免在生產環境中出現嚴重的故障。例如,一個 API 接口可能在某些特定的輸入下返回錯誤的數據,如果沒有進行測試,用戶在使用時就會遇到問題😣。
  • 保證代碼質量:編寫測試用例可以促使開發者編寫更加健壯、可維護的代碼。當我們為代碼編寫測試時,會更加關注代碼的結構和邏輯,從而提高代碼的整體質量。
  • 支持重構:隨著項目的發展,代碼可能需要進行重構以適應新的需求。有了完善的測試用例,我們可以在重構代碼的過程中快速驗證代碼的功能是否仍然正常,確保重構不會引入新的問題。
  • 提高團隊協作效率:測試用例可以作為一種文檔,讓團隊成員更好地理解代碼的功能和預期行為。當新成員加入項目時,通過運行測試用例可以快速了解代碼的工作原理。

10.1.2 DRF 測試的特點

DRF 作為一個強大的 Django 擴展,其測試具有一些獨特的特點:

  • 與 Django 集成緊密:DRF 是建立在 Django 之上的,因此可以充分利用 Django 提供的測試工具和框架。Django 提供了豐富的測試類和方法,如 TestCaseAPIClient 等,使得我們可以方便地編寫和運行測試用例。
  • 針對 API 測試優化:DRF 主要用于構建 RESTful API,所以其測試重點在于對 API 接口的測試。我們可以輕松地模擬 HTTP 請求,檢查 API 的響應是否符合預期。例如,使用 APIClient 可以模擬 GET、POST、PUT、DELETE 等請求,驗證 API 的功能和性能。
  • 支持序列化器和視圖測試:DRF 中的序列化器和視圖是核心組件,測試這些組件可以確保數據的正確序列化和反序列化,以及視圖的邏輯正確性。我們可以單獨測試序列化器的序列化和反序列化功能,也可以測試視圖對不同請求的處理。
  • 處理認證和權限:在實際的 API 應用中,認證和權限是非常重要的部分。DRF 測試可以模擬不同的認證方式和權限設置,確保只有授權的用戶才能訪問受保護的資源。

10.2 編寫測試用例

10.2.1 測試視圖

視圖是 DRF 中處理 HTTP 請求的核心組件,測試視圖可以確保其功能的正確性。以下是編寫視圖測試用例的一般步驟:

  1. 導入必要的模塊
from django.test import TestCase, APIClient
from django.urls import reverse
from your_app.models import YourModel  # 假設你的視圖與某個模型相關
  1. 創建測試類
class YourViewTestCase(TestCase):def setUp(self):# 在每個測試方法執行前進行一些初始化操作,例如創建測試數據self.client = APIClient()self.your_model = YourModel.objects.create(name='Test Object')self.url = reverse('your-view-name')  # 根據視圖的 URL 名稱獲取 URLdef test_get_view(self):# 測試 GET 請求response = self.client.get(self.url)self.assertEqual(response.status_code, 200)  # 檢查響應狀態碼是否為 200# 可以進一步檢查響應數據的內容self.assertEqual(len(response.data), 1)def test_post_view(self):# 測試 POST 請求data = {'name': 'New Object'}response = self.client.post(self.url, data, format='json')self.assertEqual(response.status_code, 201)  # 檢查響應狀態碼是否為 201(創建成功)# 可以檢查數據庫中是否新增了記錄self.assertEqual(YourModel.objects.count(), 2)

10.2.2 測試序列化器

序列化器用于將模型實例轉換為 JSON 數據,以及將 JSON 數據反序列化為模型實例。測試序列化器可以確保數據的正確轉換。

  1. 導入必要的模塊
from django.test import TestCase
from your_app.serializers import YourSerializer
from your_app.models import YourModel
  1. 創建測試類
class YourSerializerTestCase(TestCase):def setUp(self):self.your_model = YourModel.objects.create(name='Test Object')def test_serializer(self):# 測試序列化功能serializer = YourSerializer(self.your_model)data = serializer.dataself.assertEqual(data['name'], 'Test Object')def test_deserializer(self):# 測試反序列化功能data = {'name': 'New Object'}serializer = YourSerializer(data=data)self.assertTrue(serializer.is_valid())  # 檢查數據是否有效new_object = serializer.save()self.assertEqual(new_object.name, 'New Object')

10.2.3 測試認證與權限

在 DRF 中,認證和權限是保護 API 資源的重要機制。測試認證和權限可以確保只有授權的用戶才能訪問受保護的資源。

  1. 導入必要的模塊
from django.test import TestCase, APIClient
from django.urls import reverse
from rest_framework.authtoken.models import Token
from your_app.models import YourModel
from your_app.views import YourProtectedView
  1. 創建測試類
class AuthenticationAndPermissionTestCase(TestCase):def setUp(self):self.client = APIClient()self.your_model = YourModel.objects.create(name='Test Object')self.url = reverse('your-protected-view-name')# 創建一個用戶并獲取其令牌self.user = User.objects.create_user(username='testuser', password='testpass')self.token = Token.objects.create(user=self.user)def test_unauthenticated_access(self):# 測試未認證用戶的訪問response = self.client.get(self.url)self.assertEqual(response.status_code, 401)  # 檢查響應狀態碼是否為 401(未認證)def test_authenticated_access(self):# 測試認證用戶的訪問self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key)response = self.client.get(self.url)self.assertEqual(response.status_code, 200)  # 檢查響應狀態碼是否為 200

10.3 運行測試與覆蓋率分析

10.3.1 使用 Django 的測試運行器

Django 提供了一個內置的測試運行器,可以方便地運行我們編寫的測試用例。在項目的根目錄下,使用以下命令來運行測試:

python manage.py test

這個命令會自動發現項目中所有以 test 開頭的測試文件和測試類,并執行其中的測試方法。運行測試時,Django 會創建一個測試數據庫,確保測試不會影響到生產數據庫。

如果只想運行某個特定的測試模塊或測試類,可以指定其路徑:

python manage.py test your_app.tests.YourTestCase

10.3.2 分析測試覆蓋率

測試覆蓋率是衡量測試用例對代碼的覆蓋程度的指標。通過分析測試覆蓋率,我們可以了解哪些代碼還沒有被測試到,從而有針對性地編寫更多的測試用例。

要分析測試覆蓋率,我們可以使用 coverage.py 工具。首先,安裝 coverage.py

pip install coverage

然后,使用以下命令來運行測試并生成覆蓋率報告:

coverage run --source='.' manage.py test

--source='.' 表示要分析整個項目的代碼覆蓋率。運行完測試后,使用以下命令生成 HTML 格式的覆蓋率報告:

coverage html

這會在項目根目錄下生成一個 htmlcov 文件夾,打開其中的 index.html 文件,就可以在瀏覽器中查看詳細的覆蓋率報告。報告中會顯示哪些代碼行被測試到了,哪些還沒有被覆蓋,幫助我們找出測試的不足之處。😎

通過以上步驟,我們可以全面地對 DRF 項目進行測試和覆蓋率分析,確保項目的質量和穩定性。

第十一章 性能優化與擴展

11.1 性能優化

11.1.1 數據庫查詢優化

在應用程序中,數據庫查詢往往是性能瓶頸之一。以下是一些常見的數據庫查詢優化方法:

1. 索引優化
  • 創建合適的索引:索引可以加快數據庫的查詢速度。例如,在經常用于查詢條件的字段上創建索引。假如有一個用戶表,經常根據用戶的郵箱進行查詢,那么可以在郵箱字段上創建索引。
-- 在 MySQL 中為用戶表的郵箱字段創建索引
CREATE INDEX idx_user_email ON users (email);
  • 避免過多索引:雖然索引可以提高查詢速度,但過多的索引會增加數據插入、更新和刪除的開銷,因為每次數據變更時,數據庫都需要更新相應的索引。
2. 減少查詢字段
  • 只查詢需要的字段:避免使用 SELECT *,而是明確指定需要查詢的字段。例如,只需要查詢用戶的姓名和郵箱時:
# Django 示例
users = User.objects.values('name', 'email')

這樣可以減少數據庫傳輸的數據量,提高查詢性能。

3. 批量操作
  • 批量插入和更新:當需要插入或更新大量數據時,使用批量操作可以減少與數據庫的交互次數。例如,在 Django 中批量插入數據:
users = [User(name='user1', email='user1@example.com'), User(name='user2', email='user2@example.com')]
User.objects.bulk_create(users)
4. 優化查詢語句
  • 合理使用 JOIN:在使用 JOIN 操作時,確保關聯字段上有索引,并且盡量減少不必要的 JOIN 操作。
  • 使用子查詢或 CTE(公共表表達式):對于復雜的查詢,可以使用子查詢或 CTE 來提高查詢的可讀性和性能。

11.1.2 序列化器性能優化

序列化器在將數據對象轉換為可傳輸的格式(如 JSON)時,也可能會影響性能。以下是一些序列化器性能優化的方法:

1. 選擇合適的序列化器
  • 使用 ModelSerializer 的優化功能:在 Django REST Framework 中,ModelSerializer 可以自動處理模型字段的序列化。可以通過 fields 屬性指定需要序列化的字段,避免序列化不必要的字段。
from rest_framework import serializers
from .models import Userclass UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ('name', 'email')
2. 緩存序列化結果
  • 使用緩存機制:如果某些數據的序列化結果不經常變化,可以將其緩存起來,避免重復序列化。例如,使用 Django 的緩存框架:
from django.core.cache import cache
from .serializers import UserSerializer
from .models import Userdef get_user_serialized_data(user_id):cached_data = cache.get(f'user_{user_id}_serialized')if cached_data:return cached_datauser = User.objects.get(id=user_id)serializer = UserSerializer(user)serialized_data = serializer.datacache.set(f'user_{user_id}_serialized', serialized_data, 60 * 60)  # 緩存 1 小時return serialized_data
3. 優化嵌套序列化
  • 減少嵌套序列化的深度:如果序列化器中存在嵌套關系,盡量減少嵌套的深度,避免不必要的遞歸序列化。可以使用 SerializerMethodField 來手動處理嵌套數據。

11.1.3 視圖性能優化

視圖是處理請求和返回響應的關鍵部分,以下是一些視圖性能優化的方法:

1. 緩存視圖結果
  • 使用 Django 的緩存裝飾器:對于一些不經常變化的視圖,可以使用 Django 的緩存裝飾器來緩存視圖的響應結果。
from django.views.decorators.cache import cache_page@cache_page(60 * 15)  # 緩存 15 分鐘
def my_view(request):# 視圖邏輯return HttpResponse('Hello, World!')
2. 異步視圖
  • 使用異步編程:在 Django 3.1 及以上版本中,支持異步視圖。對于一些 I/O 密集型的操作,使用異步視圖可以提高并發性能。
import asyncio
from django.http import HttpResponseasync def async_view(request):await asyncio.sleep(1)  # 模擬異步操作return HttpResponse('Async View')
3. 分頁和限流
  • 分頁:對于返回大量數據的視圖,使用分頁可以減少單次請求返回的數據量,提高響應速度。在 Django REST Framework 中,可以使用 PageNumberPaginationLimitOffsetPagination
from rest_framework.pagination import PageNumberPagination
from rest_framework.viewsets import ModelViewSet
from .models import User
from .serializers import UserSerializerclass CustomPagination(PageNumberPagination):page_size = 10page_size_query_param = 'page_size'max_page_size = 100class UserViewSet(ModelViewSet):queryset = User.objects.all()serializer_class = UserSerializerpagination_class = CustomPagination
  • 限流:限制用戶的請求頻率,防止惡意請求或過度請求導致服務器性能下降。在 Django REST Framework 中,可以使用 throttling 模塊。

11.2 擴展 DRF 功能

11.2.1 自定義渲染器

渲染器用于將序列化后的數據轉換為特定的格式,如 JSON、XML 等。以下是自定義渲染器的步驟:

1. 創建自定義渲染器類
from rest_framework.renderers import BaseRendererclass CustomRenderer(BaseRenderer):media_type = 'text/plain'format = 'txt'def render(self, data, accepted_media_type=None, renderer_context=None):if isinstance(data, str):return data.encode()return str(data).encode()
2. 在視圖中使用自定義渲染器
from rest_framework.views import APIView
from rest_framework.response import Response
from .renderers import CustomRendererclass CustomView(APIView):renderer_classes = [CustomRenderer]def get(self, request):data = 'This is a custom rendered response.'return Response(data)

11.2.2 自定義解析器

解析器用于將請求中的數據解析為 Python 對象。以下是自定義解析器的步驟:

1. 創建自定義解析器類
from rest_framework.parsers import BaseParserclass CustomParser(BaseParser):media_type = 'text/plain'def parse(self, stream, media_type=None, parser_context=None):data = stream.read().decode()return data
2. 在視圖中使用自定義解析器
from rest_framework.views import APIView
from rest_framework.response import Response
from .parsers import CustomParserclass CustomParserView(APIView):parser_classes = [CustomParser]def post(self, request):data = request.datareturn Response({'received': data})

11.2.3 集成第三方庫擴展功能

DRF 可以與許多第三方庫集成,以擴展其功能。以下是一些常見的集成示例:

1. 集成 Django Filter
  • 安裝pip install django-filter
  • 配置:在 settings.py 中添加 'django_filters'INSTALLED_APPS
  • 使用:在視圖中使用 DjangoFilterBackend 進行過濾。
from rest_framework import viewsets
from django_filters.rest_framework import DjangoFilterBackend
from .models import User
from .serializers import UserSerializerclass UserViewSet(viewsets.ModelViewSet):queryset = User.objects.all()serializer_class = UserSerializerfilter_backends = [DjangoFilterBackend]filterset_fields = ['name', 'email']
2. 集成 Django REST Swagger
  • 安裝pip install django-rest-swagger
  • 配置:在 urls.py 中添加 Swagger 的路由。
from rest_framework_swagger.views import get_swagger_viewschema_view = get_swagger_view(title='API Documentation')urlpatterns = [path('swagger/', schema_view),# 其他路由
]

這樣就可以通過訪問 /swagger/ 查看 API 文檔。🎉

通過以上的性能優化和功能擴展方法,可以讓你的 DRF 應用更加高效和強大。👍

第十二章 項目實戰

12.1 項目需求分析

12.1.1 確定項目功能

在開啟一個項目之前,明確其功能是至關重要的,就像是建造一座房子,得先有清晰的設計藍圖🧐。以下是確定項目功能的具體步驟:

1. 與客戶或利益相關者溝通
  • 這是獲取需求的第一步,要積極主動地與他們交流,了解他們對項目的期望和目標。可以通過會議、問卷調查等方式收集信息。
  • 例如,開發一個電商平臺,與客戶溝通后得知他們希望平臺具備商品展示、購物車、訂單管理、用戶評價等功能。
2. 市場調研
  • 研究同類型的項目,了解市場上已有的功能和用戶的需求趨勢。分析競爭對手的優勢和不足,從中獲取靈感。
  • 比如,在開發社交軟件時,發現其他社交軟件有實時聊天、朋友圈、群組等功能,并且用戶對隱私設置有較高的需求,那么在確定項目功能時可以考慮加入這些元素。
3. 功能優先級排序
  • 確定了所有可能的功能后,需要根據重要性和緊急程度對它們進行排序。優先實現核心功能,確保項目的基本可用性。
  • 以在線教育平臺為例,課程展示、學習視頻播放、學員注冊登錄等功能是核心功能,應該優先開發;而一些輔助功能,如課程推薦算法等,可以在后續階段逐步完善。

12.3.2 設計數據庫模型

數據庫模型就像是項目的數據倉庫,合理的設計能夠提高數據的存儲效率和查詢性能📦。以下是設計數據庫模型的一般步驟:

1. 確定實體
  • 實體是數據庫中要存儲的對象,通常對應項目中的業務概念。例如,在一個圖書館管理系統中,實體可能包括書籍、讀者、借閱記錄等。
2. 定義實體的屬性
  • 每個實體都有自己的屬性,這些屬性描述了實體的特征。以書籍實體為例,屬性可能包括書名、作者、出版社、出版日期等。
3. 確定實體之間的關系
  • 實體之間存在著各種關系,如一對一、一對多、多對多等。在圖書館管理系統中,一個讀者可以借閱多本書,這就是一對多的關系;而一本書可能有多個作者,這是多對多的關系。
4. 繪制 E-R 圖(實體 - 關系圖)
  • E-R 圖是一種直觀的表示數據庫模型的工具,它能夠清晰地展示實體、屬性和關系之間的聯系。通過 E-R 圖,可以更好地理解和設計數據庫。
5. 選擇合適的數據庫管理系統
  • 根據項目的需求和特點,選擇合適的數據庫管理系統,如 MySQL、Oracle、MongoDB 等。不同的數據庫管理系統有不同的特點和適用場景。

12.2 項目開發

12.2.1 搭建項目框架

搭建項目框架就像是為項目搭建一個骨架,為后續的開發工作提供基礎和結構🏗?。以下是搭建項目框架的一般步驟:

1. 選擇開發語言和框架
  • 根據項目的需求和團隊的技術棧,選擇合適的開發語言和框架。例如,開發 Web 應用可以選擇 Python 的 Django 或 Flask 框架,Java 的 Spring 框架等。
2. 創建項目目錄結構
  • 一個清晰的目錄結構有助于代碼的組織和管理。通常包括靜態文件目錄、模板文件目錄、視圖文件目錄、模型文件目錄等。
3. 配置環境
  • 安裝和配置開發所需的環境,包括數據庫、服務器等。確保環境的穩定性和兼容性。
4. 初始化項目
  • 使用框架提供的命令初始化項目,生成必要的文件和配置。例如,在 Django 中可以使用 django-admin startproject 命令創建項目。

12.2.2 實現序列化器、視圖、路由等

1. 序列化器
  • 序列化器用于將數據庫中的數據轉換為前端可以使用的格式,如 JSON 或 XML。它還可以將前端傳來的數據進行驗證和反序列化,存儲到數據庫中。
  • 例如,在 Django REST framework 中,可以定義一個序列化器類來處理用戶信息的序列化和反序列化:
from rest_framework import serializers
from .models import Userclass UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['id', 'username', 'email']
2. 視圖
  • 視圖是處理業務邏輯的核心部分,它接收請求并返回響應。可以根據不同的業務需求,創建不同類型的視圖,如列表視圖、詳情視圖、創建視圖等。
  • 以下是一個簡單的 Django 視圖示例:
from django.http import JsonResponse
from .models import User
from .serializers import UserSerializerdef user_list(request):users = User.objects.all()serializer = UserSerializer(users, many=True)return JsonResponse(serializer.data, safe=False)
3. 路由
  • 路由用于將請求映射到相應的視圖。通過定義路由規則,可以讓用戶訪問不同的頁面和功能。
  • 在 Django 中,可以在 urls.py 文件中定義路由:
from django.urls import path
from .views import user_listurlpatterns = [path('users/', user_list, name='user_list'),
]

12.2.3 配置認證、權限、節流等功能

1. 認證
  • 認證用于驗證用戶的身份,確保只有合法的用戶才能訪問系統的資源。常見的認證方式包括用戶名密碼認證、Token 認證、OAuth 認證等。
  • 在 Django REST framework 中,可以通過配置認證類來實現認證功能:
REST_FRAMEWORK = {'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication',]
}
2. 權限
  • 權限用于控制用戶對資源的訪問權限,不同的用戶角色可能具有不同的權限。例如,管理員可以對所有資源進行增刪改查操作,而普通用戶只能查看部分資源。
  • 在 Django REST framework 中,可以定義權限類來實現權限控制:
from rest_framework.permissions import BasePermissionclass IsAdminUser(BasePermission):def has_permission(self, request, view):return request.user.is_superuser
3. 節流
  • 節流用于限制用戶對系統資源的訪問頻率,防止惡意攻擊和濫用。例如,可以限制用戶在一定時間內的請求次數。
  • 在 Django REST framework 中,可以配置節流類來實現節流功能:
REST_FRAMEWORK = {'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle','rest_framework.throttling.UserRateThrottle'],'DEFAULT_THROTTLE_RATES': {'anon': '100/day','user': '1000/day'}
}

12.3 項目測試與部署

12.3.1 編寫測試用例并進行測試

編寫測試用例是確保項目質量的重要環節,它可以幫助我們發現代碼中的缺陷和問題🧪。以下是編寫測試用例并進行測試的一般步驟:

1. 確定測試范圍
  • 明確要測試的功能和模塊,包括接口測試、單元測試、集成測試等。
2. 編寫測試用例
  • 根據測試范圍,編寫詳細的測試用例,包括測試場景、輸入數據、預期輸出等。
  • 例如,對于一個用戶注冊接口的測試用例可以如下:
    | 測試場景 | 輸入數據 | 預期輸出 |
    | ---- | ---- | ---- |
    | 正常注冊 | 用戶名:testuser,密碼:testpassword,郵箱:test@example.com | 注冊成功,返回用戶信息和 Token |
    | 用戶名已存在 | 用戶名:existinguser,密碼:testpassword,郵箱:test@example.com | 注冊失敗,返回錯誤信息 |
3. 執行測試
  • 使用測試框架(如 Django 的測試框架、JUnit 等)執行測試用例,并記錄測試結果。
4. 分析測試結果
  • 對測試結果進行分析,找出失敗的測試用例,并定位問題所在。修復問題后,重新執行測試,直到所有測試用例都通過。

12.3.2 部署項目到生產環境

將項目部署到生產環境是項目上線的最后一步,它需要確保項目在生產環境中穩定運行🚀。以下是部署項目到生產環境的一般步驟:

1. 選擇部署方式
  • 常見的部署方式包括物理服務器部署、云服務器部署、容器化部署等。根據項目的規模和需求,選擇合適的部署方式。
2. 配置生產環境
  • 安裝和配置生產環境所需的軟件和服務,如 Web 服務器、數據庫服務器等。確保環境的安全性和穩定性。
3. 部署代碼
  • 將項目代碼部署到生產服務器上,可以使用版本控制系統(如 Git)進行代碼管理。
4. 配置域名和 SSL 證書
  • 為項目配置域名,并安裝 SSL 證書,確保用戶訪問的安全性。
5. 進行性能優化
  • 對項目進行性能優化,包括數據庫優化、代碼優化、緩存優化等,提高項目的響應速度和吞吐量。
6. 監控和維護
  • 部署完成后,需要對項目進行監控和維護,及時發現和解決問題,確保項目的穩定運行。可以使用監控工具(如 Prometheus、Grafana 等)對項目的性能指標進行監控。

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

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

相關文章

如何解決 Python 項目安裝依賴報錯:ERROR: Failed to build installable wheels for some pyproject.toml based project

如何解決 Python 項目安裝依賴報錯&#xff1a;ERROR: Failed to build installable wheels for some pyproject.toml based projects 在使用 pip 安裝 Python 項目的依賴時&#xff0c;遇到類似如下的報錯信息&#xff1a; ERROR: Failed to build installable wheels for s…

使用f5-tts訓練自己的模型筆記

摘要 服務器都有了&#xff0c;這不得練練丹&#xff0c;有點說不過去啊。所以嘗試了從頭開始訓練一個模型&#xff0c;結果由于推理頁面好像有bug&#xff0c;不知道是不是失敗了&#xff0c;然后又嘗試微調一下模型。本篇文章主要記錄了三流調包俠嘗試煉丹過程中學習到的一些…

安全可控的AI底座:燈塔大模型應用開發平臺全面實現國產信創兼容適配認證

國產信創產品兼容適配認證是為了支持和推動國產信息技術產品和服務的發展而設立的一種質量標準和管理體系。適配認證旨在確保相關產品在安全性、可靠性、兼容性等方面達到一定的標準&#xff0c;以滿足政府和關鍵行業對信息安全和自主可控的需求。 北京中煙創新科技有限公司&a…

初識Vue【1】

1.什么是Vue&#xff1a; Vue (讀音 /vju?/&#xff0c;類似于 **view**) 是一套用于構建用戶界面的**漸進式框架**。與其它大型框架不同的是&#xff0c;Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注視圖層&#xff0c;不僅易于上手&#xff0c;還便于與第三方庫或…

Jest入門

快速入門 Jest中文文檔 | Jest中文網 1.下載&#xff1a;npm install --save-dev jest 2.創建 sum.js 文件&#xff1a; function sum(a, b) { return a b; } module.exports sum; 3.創建sum.test.js 的文件 const sum require(./sum); test(adds 1 2 to equal 3,…

Spring Boot企業級開發五大核心功能與高級擴展實戰

前言 在企業級應用開發中&#xff0c;Spring Boot已成為事實上的Java開發標準。本文將從企業實際需求出發&#xff0c;深入剖析Spring Boot五大必用核心功能&#xff0c;并擴展講解三項高級開發技能&#xff0c;幫助開發者掌握構建健壯、高效、易維護的企業級應用的必備技術。…

2025電工杯數學建模B題思路數模AI提示詞工程

我發布的智能體鏈接&#xff1a;數模AI扣子是新一代 AI 大模型智能體開發平臺。整合了插件、長短期記憶、工作流、卡片等豐富能力&#xff0c;扣子能幫你低門檻、快速搭建個性化或具備商業價值的智能體&#xff0c;并發布到豆包、飛書等各個平臺。https://www.coze.cn/search/n…

LabVIEW開發FPGA磁聲發射應力檢測系統

工業級磁聲發射應力檢測系統&#xff0c;針對傳統設備參數固定、靈活性不足的痛點&#xff0c;采用 Xilinx FPGA 與 LabVIEW 構建核心架構&#xff0c;實現激勵信號可調、多維度數據采集與實時分析。系統適用于鐵磁性材料應力檢測場景&#xff0c;具備高集成度、抗干擾性強、檢…

Java IO流學習指南:從小白到入門

Java的IO&#xff08;Input/Output&#xff09;流是處理數據輸入和輸出的基礎。無論是讀取文件、寫入文件&#xff0c;還是通過網絡傳輸數據&#xff0c;IO流都無處不在。對于剛接觸Java的新手&#xff0c;理解IO流可能會有些困惑&#xff0c;但別擔心&#xff0c;今天我們將一…

【后端高階面經:微服務篇】1、微服務架構核心:服務注冊與發現之AP vs CP選型全攻略

一、CAP理論在服務注冊與發現中的落地實踐 1.1 CAP三要素的技術權衡 要素AP模型實現CP模型實現一致性最終一致性&#xff08;Eureka通過異步復制實現&#xff09;強一致性&#xff08;ZooKeeper通過ZAB協議保證&#xff09;可用性服務節點可獨立響應&#xff08;支持分區存活…

QNAP NEXTCLOUD 域名訪問

我是用docker compose方式安裝的&#xff0c;雖然不知道是不是這么個叫法&#xff0c;廢話不多說。 背景&#xff1a;威聯通container station安裝了nextcloud和lucky&#xff0c;lucky進行的域名解析和反代 先在想安裝的路徑、數據存儲路徑、數據庫路徑等新建文件夾。再新建…

高級SQL技巧:窗口函數與復雜查詢優化實戰

高級SQL技巧&#xff1a;窗口函數與復雜查詢優化實戰 開篇&#xff1a;數據庫開發中的挑戰 在現代企業級應用中&#xff0c;數據庫不僅是存儲數據的核心組件&#xff0c;更是處理復雜業務邏輯的重要工具。然而&#xff0c;隨著數據量和并發請求的不斷增長&#xff0c;傳統的S…

《STL--list的使用及其底層實現》

引言&#xff1a; 上次我們學習了容器vector的使用及其底層實現&#xff0c;今天我們再來學習一個容器list&#xff0c; 這里的list可以參考我們之前實現的單鏈表&#xff0c;但是這里的list是雙向循環帶頭鏈表&#xff0c;下面我們就開始list的學習了。 一&#xff1a;list的…

docker中使用openresty

1.為什么要使用openresty 我這邊是因為要使用1Panel&#xff0c;第一個最大的原因&#xff0c;就是圖方便&#xff0c;比較可以一鍵安裝。但以前一直都是直接安裝nginx。所以需要一個過度。 2.如何查看openResty使用了nginx哪個版本 /usr/local/openresty/nginx/sbin/nginx …

vscode包含工程文件路徑

在 VSCode 中配置 includePath 以自動識別并包含上層目錄及其所有子文件夾&#xff0c;需結合通配符和相對/絕對路徑實現。以下是具體操作步驟及原理說明&#xff1a; 1. 使用通配符 ** 遞歸包含所有子目錄 在 c_cpp_properties.json 的 includePath 中&#xff0c;${workspac…

【排序算法】典型排序算法 Java實現

以下是典型的排序算法分類及對應的 Java 實現&#xff0c;包含時間復雜度、穩定性說明和核心代碼示例&#xff1a; 一、比較類排序&#xff08;通過元素比較&#xff09; 1. 交換排序 ① 冒泡排序 時間復雜度&#xff1a;O(n)&#xff08;優化后最優O(n)&#xff09; 穩定性&…

多模態大語言模型arxiv論文略讀(八十七)

MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ?? 論文標題&#xff1a;MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ?? 論文作者&#xff1a;Xiangyu Zhao, Xiangtai Li, Haodong Duan, Haian Huang, Yining Li, Kai Chen, Hua Ya…

塔能節能平板燈:點亮蘇州某零售工廠節能之路

在蘇州某零售工廠的運營成本中&#xff0c;照明能耗占據著一定比例。為降低成本、提升能源利用效率&#xff0c;該工廠與塔能科技攜手&#xff0c;引入塔能節能平板燈&#xff0c;開啟了精準節能之旅&#xff0c;并取得了令人矚目的成效。 一、工廠照明能耗困境 蘇州該零售工廠…

數據庫事務的四大特性(ACID)

一、前言 在現代數據庫系統中&#xff0c;事務&#xff08;Transaction&#xff09;是確保數據一致性和完整性的重要機制。事務的四大特性——原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔離性&#xff08;Isolation&#xff09;…

8 種快速易用的Python Matplotlib數據可視化方法

你是否曾經面對一堆復雜的數據&#xff0c;卻不知道如何讓它們變得直觀易懂&#xff1f;別慌&#xff0c;Python 的 Matplotlib 庫是你數據可視化的最佳伙伴&#xff01;它簡單易用、功能強大&#xff0c;能將枯燥的數字變成引人入勝的圖表。無論是學生、數據分析師還是程序員&…