Django 无需重写save方法的模型字段值保存前替换实现方案
可行实现方案
以下两种方案都无需逐个重写模型的.save()方法,可统一维护字符转换逻辑:
方案1:自定义波斯语专用字段(优先推荐)
自定义继承自Django原生CharField的字段类,内部封装字符映射逻辑,仅需要将原有需要处理的CharField替换为该自定义字段即可。
from django.db import models # 阿拉伯语到波斯语的字符映射表,可根据需求补充更多映射规则 ARABIC_TO_PERSIAN_MAP = { 'ي': 'ی', 'ك': 'ک', '٠': '۰', '١': '۱', '٢': '۲', '٣': '۳', '٤': '۴', '٥': '۵', '٦': '۶', '٧': '۷', '٨': '۸', '٩': '۹' } def convert_arabic_to_persian(value): if not isinstance(value, str): return value for arabic_char, persian_char in ARABIC_TO_PERSIAN_MAP.items(): value = value.replace(arabic_char, persian_char) return value class PersianCharField(models.CharField): def pre_save(self, model_instance, add): original_value = getattr(model_instance, self.attname) converted_value = convert_arabic_to_persian(original_value) setattr(model_instance, self.attname, converted_value) return super().pre_save(model_instance, add)
使用方式:
将原有模型中需要处理的字段定义从name = models.CharField(max_length=100)
替换为name = PersianCharField(max_length=100)即可。
方案2:使用pre_save全局信号
如果不想修改原有字段的定义,可通过全局pre_save信号监听模型保存动作,仅需要给对应模型新增待转换字段的配置属性即可,对原有业务代码侵入性更低。
from django.db.models.signals import pre_save from django.dispatch import receiver # 此处复用方案1中的convert_arabic_to_persian函数和映射表 @receiver(pre_save) def persian_char_convert_handler(sender, instance, **kwargs): # 仅处理配置了persian_fields属性的模型 if not hasattr(sender, 'persian_fields'): return for field_name in sender.persian_fields: original_value = getattr(instance, field_name, None) converted_value = convert_arabic_to_persian(original_value) setattr(instance, field_name, converted_value)
使用方式:
在需要处理的模型中新增persian_fields配置项即可,示例:
class Person(models.Model): name = models.CharField(max_length=100) desc = models.TextField() # 指定需要做字符转换的字段 persian_fields = ['name', 'desc']
两种方案都支持灵活指定需要转换的字段,逻辑统一维护,后续新增模型时无需重复编写转换逻辑。
内容的提问来源于stack exchange,提问作者FooBar
相关产品推荐
相关产品推荐

