使用具有可怕架构的旧数据库,并且想要重命名几个ModelSerializer字段,而不必重新定义模型中已经定义的字段。
这是一个示例模型:
class LegacyItem(models.Model):
# Note: ignore things that feel "wrong" here (just an example)
legacyitem_id = models.IntegerField(primary_key=True)
legacyitem_notes = models.CharField(max_length=4000, blank=True, null=True)
directory_id = models.ForeignKey('Directory', models.DO_NOTHING)
created_by_directory_id = models.ForeignKey('Directory', models.DO_NOTHING)
created_date = models.DateField(auto_now_add=True)
modified_by_directory_id = models.ForeignKey('Directory', models.DO_NOTHING)
modified_date = models.DateField(auto_now=True)
这是一个有效的序列化器:
class LegacyItemSerializer(serializers.ModelSerializer):
class Meta:
fields = '__all__'
model = LegacyItem
read_only_fields = [
'created_date',
'modified_date',
]
目标是为API批量重命名模型字段,以便我们可以抽象出可怕的模式。这是一个正在工作的序列化程序,显示了我们想要进行的重命名:
class LegacyItemSerializer(serializers.ModelSerializer):
created_by = serializers.PrimaryKeyRelatedField(
read_only=True,
source='created_by_directory_id',
)
customer = serializers.PrimaryKeyRelatedField(
queryset=Directory.objects.all(),
source='directory_id',
)
id = serializers.PrimaryKeyRelatedField(
read_only=True,
source='legacyitem_id'
)
modified_by = serializers.PrimaryKeyRelatedField(
read_only=True,
source='modified_by_directory_id',
)
notes = serializers.DateField(source='legacyitem_notes')
class Meta:
fields = [
'id',
'customer',
'notes',
'created_by',
'created_date',
'modified_by',
'modified_date',
]
model = LegacyItem
read_only_fields = [
'created_date',
'modified_date',
]
我们要做的就是重命名字段。我们不想更改验证,而是希望将大部分验证保留在模型和模型字段中,而不是将其也放入序列化程序中。我们将不得不对许多模型进行此类操作,并且在序列化器上复制模型验证以重命名字段是非常繁琐和不道德的做法(IMO)。
是否有DRY方法可以做到这一点?也许我们可以在LegacyItemSerializer.Meta中添加某些内容,或者可以重写某些方法?例如,在使用Django表单时,可以通过在ModelForm.Meta中调整标签/窗口小部件来轻松实现此目的。您将无需重新定义ModelForm字段/验证。
在一个完美的世界中,也许像这样:
class LegacyItemSerializer(serializers.ModelSerializer):
class Meta:
model = LegacyItem
model_field_args = {
'legacyitem_id': {'name': 'id'},
'directory_id': {'name': 'customer'},
'legacyitem_notes': {'name': 'notes'},
'created_by_directory_id': {'name': 'created_by'},
'modified_by_directory_id': {'name': 'modified_by'},
}