如何在Django Model Serializer中实现透传字段?
问题描述
我是Django Rest Framework(DRF)新手,现在通过AJAX调用后端DRF API,希望传递请求成功后UI中要调用的JavaScript函数名称,用同一个AJAX函数处理多个UI交互,返回时动态执行对应的成功回调方法。
当前AJAX函数逻辑如下:
var saveEditedData = function (event) { let parentElement = event.parentElement; let enctype = (event.enctype) ? event.enctype : "application/x-www-form-urlencoded"; let method = (event.method) ? event.method : "POST"; $.ajax({ cache: false, contentType: false, data: event.data, enctype: enctype, processData: false, type: method, url: event.url, success: function (response){ console.log(response); if (response['onSuccessFn']){ successFns[response['onSuccessFn']](response); } }, error: function (response) { let errors = response["responseJSON"]["errors"]; displayErrors(parentElement, errors); } }); }
我使用的DRF序列化器及示例入站数据如下:
class DocumentCategorySerializer(serializers.ModelSerializer): id = serializers.ReadOnlyField() on_success_fn = serializers.SerializerMethodField() class Meta: model = DocumentCategory fields = ['id', 'name', 'description', 'on_success_fn'] def get_on_success_fn(self, obj): return self.data['on_success_fn']
示例入站数据
- name: TestCategory
- description: Testing this
- on_success_fn: addCategorySuccessFn
现在遇到的问题是:模型序列化器的所有字段都来自数据库,添加的SerializerMethodField无法透传输入值,需要实现一个“透传”字段——输入什么值就输出什么值。
解决方案
方法一:通过临时属性+自定义序列化输出
这种方法直接在序列化器中处理,接收前端传入的字段值,临时存储到实例属性中,最后在序列化输出时加入响应:
class DocumentCategorySerializer(serializers.ModelSerializer): id = serializers.ReadOnlyField() # 定义为可读写字段,允许接收前端输入 on_success_fn = serializers.CharField(required=False, write_only=False) class Meta: model = DocumentCategory fields = ['id', 'name', 'description', 'on_success_fn'] def create(self, validated_data): # 从验证数据中取出on_success_fn,不存入数据库 on_success_fn = validated_data.pop('on_success_fn', None) # 创建模型实例 instance = super().create(validated_data) # 将值存入实例临时属性 if on_success_fn is not None: instance.on_success_fn = on_success_fn return instance def update(self, instance, validated_data): on_success_fn = validated_data.pop('on_success_fn', None) instance = super().update(instance, validated_data) if on_success_fn is not None: instance.on_success_fn = on_success_fn return instance def to_representation(self, instance): # 基础序列化输出 representation = super().to_representation(instance) # 如果实例有临时属性,添加到响应中 if hasattr(instance, 'on_success_fn') and instance.on_success_fn: representation['on_success_fn'] = instance.on_success_fn return representation
方法二:通过上下文(Context)传递字段值
这种方法在视图层获取前端传入的字段值,存入序列化器上下文,再在序列化输出时取出加入响应:
视图层代码
from rest_framework import viewsets from .models import DocumentCategory from .serializers import DocumentCategorySerializer class DocumentCategoryViewSet(viewsets.ModelViewSet): queryset = DocumentCategory.objects.all() serializer_class = DocumentCategorySerializer def perform_create(self, serializer): # 从请求数据中获取on_success_fn,存入序列化器上下文 serializer.context['on_success_fn'] = self.request.data.get('on_success_fn') serializer.save() def perform_update(self, serializer): serializer.context['on_success_fn'] = self.request.data.get('on_success_fn') serializer.save()
序列化器代码
class DocumentCategorySerializer(serializers.ModelSerializer): id = serializers.ReadOnlyField() class Meta: model = DocumentCategory fields = ['id', 'name', 'description'] def to_representation(self, instance): representation = super().to_representation(instance) # 从上下文取出字段值,添加到响应 on_success_fn = self.context.get('on_success_fn') if on_success_fn: representation['on_success_fn'] = on_success_fn return representation
为什么之前的SerializerMethodField不行?
SerializerMethodField默认是只读字段,无法接收前端传入的输入值;- 你在
get_on_success_fn中调用self.data['on_success_fn']会触发递归调用,导致程序报错。
内容的提问来源于stack exchange,提问作者SeaSky
相关产品推荐
相关产品推荐

