DRF ModelSerializer中如何将OrderedDict列表传为**kwargs实现通用翻译更新
解决方案
报错原因
你遇到的参数报错是因为初始定义的translation_update_field仅声明了1个位置形参,但调用时直接传入了多组翻译字段的有序字典参数,参数数量不匹配导致报错。你需要将多组翻译字段整合为字典后以**kwargs形式传入,同时将工具函数调整为支持接收任意数量的翻译字段参数。
通用翻译字段更新工具函数实现
首先编写全局可复用的翻译字段处理函数,兼容任意模型的泛型翻译关联场景:
from django.contrib.contenttypes.models import ContentType from .models import Translation def update_translation_fields(instance, **translation_fields): """ 批量创建/更新主实例关联的翻译字段数据 :param instance: 主模型实例(如Tags、Article等带GenericRelation关联Translation的模型) :param translation_fields: 关键字参数,键为翻译字段名,值为对应翻译数据列表 """ content_type = ContentType.objects.get_for_model(instance) # 遍历所有传入的翻译字段 for field_name, translations in translation_fields.items(): # 清空当前字段的旧翻译数据(更新场景用,可根据业务需求调整为增量更新逻辑) instance.translations.filter(field_name=field_name).delete() # 批量创建新翻译数据 Translation.objects.bulk_create([ Translation( content_type=content_type, object_id=instance.pk, field_name=field_name, language_code=item['language_code'], content=item['content'] ) for item in translations ])
序列化器调用示例
在对应ModelSerializer的create和update方法中,先将翻译字段从validated_data中移除,创建/更新主实例后调用上述工具函数即可:
from rest_framework import serializers from .models import Tags from .utils import update_translation_fields # 通用嵌套翻译序列化器,可全局复用 class TranslationSerializer(serializers.ModelSerializer): class Meta: model = Translation fields = ('language_code', 'content') class TagsSerializer(serializers.ModelSerializer): # 声明嵌套翻译字段 name = TranslationSerializer(many=True) description = TranslationSerializer(many=True) class Meta: model = Tags fields = ('id', 'name', 'description', 'create_time') def create(self, validated_data): # 提取所有翻译字段数据 translation_map = { 'name': validated_data.pop('name'), 'description': validated_data.pop('description') } # 先创建主实例 instance = super().create(validated_data) # 传入字典解包为关键字参数调用工具函数 update_translation_fields(instance, **translation_map) return instance def update(self, instance, validated_data): # 提取翻译字段,支持部分更新场景 translation_map = { 'name': validated_data.pop('name', None), 'description': validated_data.pop('description', None) } # 先更新主实例字段 instance = super().update(instance, validated_data) # 过滤未传入的字段,调用更新逻辑 valid_translation_map = {k: v for k, v in translation_map.items() if v is not None} if valid_translation_map: update_translation_fields(instance, **valid_translation_map) return instance
扩展说明
如果其他模型需要使用翻译能力,仅需要做三处改动即可,无需重复编写循环逻辑:
- 模型中添加
GenericRelation(Translation)关联 - 序列化器中声明对应字段的嵌套
TranslationSerializer create/update方法中提取翻译字段字典,调用update_translation_fields即可
内容的提问来源于stack exchange,提问作者elias_oliveira
相关产品推荐
相关产品推荐

