Django REST Framework Serializer 進階教程

1. 序列化器概述

在 Django REST Framework(DRF)中,序列化器(Serializer)用于將復雜的數據類型(如模型實例)轉換為 JSON 格式,以便于 API 返回給客戶端。此外,序列化器還可以用于驗證請求數據。

2. 基本的 ModelSerializer 使用

  1. 在 models.py 中定義了一個 Department 模型,用來表示部門的信息。在這個模型中,我們包括了 full_name 字段(存儲部門的完整名稱),以及 level 字段(表示部門的層級)。
# models.py
from django.db import modelsclass Department(models.Model):# 部門的全名,使用 `CharField` 存儲full_name = models.CharField(max_length=255)# 部門的層級,默認為 0level = models.IntegerField(default=0)def __str__(self):return self.full_name
  1. ModelSerializerSerializer 的一個子類,專門用于將 Django 模型實例轉化為 JSON 格式,且支持自動化字段映射。
例子:
from rest_framework import serializers
from .models import Departmentclass DepartmentSerializer(serializers.ModelSerializer):class Meta:model = Departmentfields = '__all__'

這里,DepartmentSerializer 會自動根據 Department 模型的字段生成相應的序列化字段。

3. 使用 SerializerMethodField 動態計算字段

SerializerMethodField 是 DRF 提供的一種特殊字段類型,用于動態計算某個字段的值。你可以定義一個方法,方法名稱是 get_<field_name>,該方法會自動被調用來計算字段的值。

示例:

假設 Department 模型有一個字段 full_name,表示部門的全名(例如:“公司-技術-后端”),我們希望計算一個 level 字段,表示該部門的層級。

from rest_framework import serializersclass DepartmentSerializer(serializers.ModelSerializer):# level 字段會動態計算level = serializers.SerializerMethodField(read_only=True)class Meta:model = Departmentfields = '__all__'# 動態計算 level 字段def get_level(self, obj):full_name = obj.full_name# 按照 '-' 分割 full_namefull_name_split = full_name.split('-')# 計算層級:忽略第一個部分(例如“公司”)return len(full_name_split) - 1

在這個示例中:

  • level 字段是一個 SerializerMethodField,它不會直接從模型中讀取,而是通過 get_level 方法動態計算。
  • get_level 方法接收 obj(即當前的 Department 實例),根據 full_name 字段來計算層級。
  • full_name.split('-') 會將部門的全名拆分為多個部分,然后計算層級。

4. 使用自定義 __init__ 方法動態控制字段

有時,我們可能需要根據外部條件來動態修改序列化器中的字段。例如,某些字段可能在某些情況下不需要序列化。我們可以通過重寫 __init__ 方法來實現這一點。

示例:
class DepartmentSerializer(serializers.ModelSerializer):level = serializers.SerializerMethodField(read_only=True)def __init__(self, *args, **kwargs):fields = kwargs.pop('fields', [])super().__init__(*args, **kwargs)if fields:# 刪除未指定的字段allowed = set(fields)existing = set(self.fields)for field_name in existing - allowed:self.fields.pop(field_name)def get_level(self, obj):full_name = obj.full_namefull_name_split = full_name.split('-')return len(full_name_split) - 1class Meta:model = Departmentfields = '__all__'depth = 1read_only_fields = ('id',)

在上面的代碼中:

  • __init__ 方法接受一個 fields 參數,該參數是一個字段列表,表示要包含的字段。
  • 如果 fields 參數不為空,它會從已有的字段中刪除未指定的字段,從而控制序列化器返回的字段。

5. 實戰案例:使用 SerializerMethodField 和自定義字段控制

背景:

假設我們要設計一個 API,返回部門的層級結構,并且根據不同的條件返回不同的字段。我們需要動態計算部門的層級,并且能夠根據請求控制返回哪些字段。

模型:
# models.py
from django.db import modelsclass Department(models.Model):full_name = models.CharField(max_length=255)level = models.IntegerField(default=0)def __str__(self):return self.full_name
視圖:
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Department
from .serializers import DepartmentSerializerclass DepartmentView(APIView):def get(self, request):# 假設我們根據參數決定返回哪些字段fields = request.query_params.getlist('fields', [])# 獲取所有部門數據departments = Department.objects.all()# 使用序列化器返回數據serializer = DepartmentSerializer(departments, many=True, fields=fields)return Response(serializer.data, status=status.HTTP_200_OK)
URL 配置:
# urls.py
from django.urls import path
from .views import DepartmentViewurlpatterns = [path('departments/', DepartmentView.as_view(), name='departments-list'),
]

6. 測試:

假設我們有以下部門數據:

full_namelevel
公司-技術-后端2
公司-財務1
公司-人力資源1
請求 1:返回所有字段
GET /departments/

返回:

[{"full_name": "公司-技術-后端","level": 2},{"full_name": "公司-財務","level": 1},{"full_name": "公司-人力資源","level": 1}
]
請求 2:僅返回 full_namelevel 字段
GET /departments/?fields=full_name&fields=level

返回:

[{"full_name": "公司-技術-后端","level": 2},{"full_name": "公司-財務","level": 1},{"full_name": "公司-人力資源","level": 1}
]

7. 總結

  • SerializerMethodField:用來動態計算字段的值,可以根據模型實例的內容或請求參數來決定字段的值。
  • get_<field_name> 方法:定義字段的計算邏輯。
  • 動態字段控制:通過在序列化器的 __init__ 方法中動態修改字段來控制序列化器返回哪些字段。
  • 實戰案例:通過 fields 參數控制返回字段,并動態計算層級。

這個案例展示了如何在 Django REST Framework 中靈活地使用序列化器來動態計算和控制返回字段,適用于多種 API 場景。

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

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

相關文章

面試問題詳解十四:Qt 多線程同步【QSemaphore】講解

在多線程開發中&#xff0c;經常需要控制多個線程對共享資源的訪問數量。例如限制同時下載文件的數量、控制數據庫連接池的連接使用等等。這時候&#xff0c;Qt 提供的 QSemaphore&#xff08;信號量&#xff09;就非常派得上用場。一、什么是 QSemaphore&#xff1f; QSemapho…

Spark mapGroups 函數詳解與多種用法示例

mapGroups 是 Spark 中一個強大的分組操作函數&#xff0c;它允許你對每個分組應用自定義邏輯并返回一個結果。以下是多個使用簡單樣例數據的具體用法示例。基礎示例數據假設我們有一個簡單的學生成績數據集&#xff1a;// 創建示例DataFrame val studentScores Seq(("Ma…

【圖論】Graphs.jl 圖數據的讀寫與生成器

文章目錄圖數據的讀寫Graphs.loadgraphGraphs.loadgraphsGraphs.savegraph保存單個圖保存圖字典Graphs.loadlg_multGraphs.savelgGraphs.savelg_mult圖的生成器1. 隨機圖模型1.1 Erd?s–Rnyi 模型1.2 巴拉巴西-阿爾伯特模型 (無標度網絡)1.3 小世界網絡模型1.4 隨機塊模型 (SB…

Go指針全解析:從基礎到實戰

基本概念與定義指針的定義指針是一種特殊的變量類型&#xff0c;它存儲的不是實際數據值&#xff0c;而是另一個變量在計算機內存中的地址。在底層實現上&#xff0c;指針本質上是保存內存位置的無符號整數&#xff0c;它直接指向內存中的特定位置&#xff0c;允許程序直接操作…

Oracle 查詢有哪些用戶 提示用戶名密碼無效

要查詢 Oracle 數據庫中的所有用戶&#xff0c;可以使用以下 SQL 查詢語句。這個查詢將返回數據庫中所有用戶的列表。 [] SELECT username FROM all_users ORDER BY username;如果你有足夠的權限&#xff08;通常是 DBA 權限&#xff09;&#xff0c;你也可以使用 dba_users 視…

小白成長之路-develops -jenkins部署lnmp平臺

文章目錄一、準備工作1.1兩臺虛擬機1.2配置文件1.3免密登錄二、實戰1.構建主item2.測試nginx,php,mysql2.1新建測試項目2.2與正式項目綁定構建后的操作2.3測試2.4導入discuz項目總結一、準備工作 1.1兩臺虛擬機 服務器&#xff1a;192.168.144.24 客戶端&#xff1a;192.168.…

【HarmonyOS 6】仿AI喚起屏幕邊緣流光特效

【HarmonyOS 6】仿AI喚起屏幕邊緣流光特效 一、前言 最近在做 HarmonyOS 6.0 的適配&#xff0c;發現 Beta1版本里多了個很實用的視效功能——自帶背景的雙邊流光。 之前做屏幕邊緣流光特效的時候&#xff0c;要么得自己寫漸變動畫拼效果&#xff0c;要么就得套好幾個組件疊層&…

跟做springboot尚品甄選項目

springbootvue3 【尚硅谷Java項目《尚品甄選》 SpringBootSpringCloud萌新學會企業級java項目】003.后臺系統-搭建前端環境&#xff08;工程創建&#xff09;_嗶哩嗶哩_bilibili E:\project\AllProJect\Shangpin Selection\項目材料素材\課件\尚品甄選項目課件 前端套用框架…

【Linux】創建線程

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 文章目錄 一、為什么需要線程&#xff1f; 創建線程 示例&#xff1a;計算斐波恩夕法 一、為什么需要線程&#xff1f; 在多核處理器的計算機上&#xff0c;線程可…

HTML應用指南:利用POST請求獲取全國九號電動車體驗店服務店位置信息

九號公司(Ninebot)作為全球領先的智能短途出行解決方案提供商,始終秉持“智慧移動,愉悅生活”的品牌理念,致力于為個人用戶打造安全、智能、時尚的城市出行體驗。依托“智能硬件 + 數字服務 + 線下觸點”三位一體的戰略布局,九號公司已建立起覆蓋全國、輻射全球的銷售與服…

Kafka面試精講 Day 4:Consumer消費者模型與消費組

【Kafka面試精講 Day 4】Consumer消費者模型與消費組 在“Kafka面試精講”系列的第四天&#xff0c;我們將深入探討Kafka的核心組件之一——Consumer消費者模型與消費組&#xff08;Consumer Group&#xff09;。這是Kafka實現高吞吐、可擴展消息消費的關鍵機制&#xff0c;也…

使用 Uni-app 打包 外鏈地址APK 及 iOS 注意事項

本文詳細介紹了如何使用 Uni-app 框架將項目打包為 Android APK 和 iOS 應用&#xff0c;重點講解了 minSdkVersion、targetSdkVersion 和 abiFilters 的配置&#xff0c;以及 iOS 開發的注意事項。文章還包含了您提供的 WebView 示例代碼&#xff0c;并提供了關鍵的注意事項&a…

異常處理小妙招——3.構造函數的安全第一原則:為什么不在構造函數中拋出異常?

文章目錄災難性的生日派對構造函數&#xff1a;對象的出生證明安全第一&#xff1a;嚴格的出生檢查為什么要在構造函數中嚴格驗證&#xff1f;1. 避免"僵尸對象"2. Fail-Fast&#xff08;快速失敗&#xff09;原則現實世界的實踐建議1. 使用工廠方法模式2. 使用Build…

iptables 和 ip route

文章目錄iptables原理及常用命令表鏈鏈表鏈表總結iptables 常用命令及參數1. 規則管理命令 (Commands)2. 規則匹配參數 (Rule-Specification - Matches)3. 目標動作參數 (Target)命令示例配置流程示例ip route常用命令iptables和ip route的聯系實用命令示例對比iptables原理及常…

RPC和HTTP的區別?

RPC和HTTP是兩種不同的通信協議&#xff0c;它們在通信方式、性能效率以及靈活性可擴展性等方面存在區別。以下是具體分析&#xff1a; 通信方式 RPC&#xff1a;RPC是基于遠程過程調用的二進制協議&#xff0c;它允許客戶端像調用本地函數一樣調用遠程服務器上的函數或方法[2]…

貝葉斯分類(Bayes Classify)

一. 核心思想貝葉斯分類是一類基于貝葉斯定理&#xff08;Bayes Theorem&#xff09;和概率統計的分類算法&#xff0c;核心思想是 “通過已知的先驗概率&#xff0c;結合數據的似然性&#xff0c;計算后驗概率&#xff0c;最終將樣本歸為后驗概率最高的類別”。它在機器學習、…

怎么熟悉業務,我是做前端的,但對業務了解沒有渠道

作為前端開發者&#xff0c;想深入了解業務但“沒有渠道”&#xff0c;這是非常普遍的痛點。很多前端同學只接到“切圖實現頁面”的任務&#xff0c;久而久之就成了“實現工具人”。但業務理解力&#xff0c;恰恰是區分“初級”和“高級”前端的核心分水嶺。 好消息是&#xff…

如何批量在PDF文檔最后一頁蓋章?

在面對上百份需要處理的 PDF 文檔時&#xff0c;逐個打開文檔蓋章再進行保存&#xff0c;這些步驟不僅提高我們工作的繁瑣&#xff0c;還容易導致處理位置錯誤或遺漏。那么怎么去將 PDF 文檔末頁實現批量自動打上電子印章&#xff1f;一般的方式沒有辦法來滿足我們高效率辦公的…

Keras/TensorFlow 中 `predict()` 函數詳細說明

Keras/TensorFlow 中 predict() 函數詳細說明 predict() 是 Keras/TensorFlow 中用于模型推理的核心方法&#xff0c;用于對輸入數據生成預測輸出。下面我將從多個維度全面介紹這個函數的用法和細節。 一、基礎語法和參數 基本形式 predictions model.predict(x,batch_sizeNon…

題解:UVA1589 象棋 Xiangqi

看到代碼別急著走&#xff0c;還要解釋呢&#xff01;哈哈&#xff0c;知道這個題我是怎么來的嗎&#xff1f;和爸爸下象棋20場輸17場和2場QWQ于是乎我就想找到一個可以自動幫我下棋的程序&#xff0c;在洛谷上面搜索&#xff0c;就搜索到了這個題。很好奇UVA的為啥空間限制是0…