django - 重用现有的 Django REST 框架序列化程序
问题描述
我目前正在使用 Django Rest Framework,并且正在寻找一种方法来重用已定义的序列化器中的某些属性。为了解释,我将公开一些涉及的序列化程序:
完成的序列化器:
class ProductSerializer(serializers.ModelSerializer):
subscribed = serializers.SerializerMethodField()
other_field = serializers.SerializerMethodField()
class Meta:
model = Product
fields = [
'id',
'name',
'subscribed',
'other_field',
'x',
'y',
'z'
]
def get_subscribed(self, product: Product):
return product.is_user_subscribed(self.context['request'].user)
简化的序列化器:
class ProductSimplifiedSerializer(serializers.ModelSerializer):
subscribed = serializers.SerializerMethodField()
class Meta:
model = Product
fields = [
'id',
'name',
'subscribed'
]
def get_subscribed(self, product: Product):
return product.is_user_subscribed(self.context['request'].user)
正如您在上面所注意到的,这些序列化程序几乎相同,但其中一个是对象的简化版本,因为我不想在某些部分检索不必要的信息。这里的问题是,在这种情况下,我们有一个需要维护两次的方法序列化程序。也许将来,我想添加另一个字段,我需要将它添加到两者中。那么,如何实现一个包含所有字段但我可以重用它并从中提取特定字段的基于序列化程序?
我已经想到了这些选项: 1. 使用 Base Serializer 实例:草稿:
def to_representation(self, instance)
desired_format = self.context['format']
if desired_format == 'simplified':
fields = ['fields_for_simplified']
elif desired_format == 'regular':
fields = ['fields_for_regular']
for field in fields:
# make the representation
使用这种方法,我不知道这是一个好主意还是可能
- 使用 SerializerField 草稿:
class UserSubscribed(serializer.SerializerField)
def to_representation(self, instance):
return 'representation'
class ProductSimplifiedSerializer(serializers.ModelSerializer):
user_subscribed = UserSubscribed()
class Meta:
model = Product
fields = [
'id',
'name',
'user_subscribed'
]
我认为最后一个更好,问题是这个 _user_subscribed_ 不是 Product 实例的属性,因此它失败了,我不知道如何实现这一点。
您对这种情况有何建议?任何意见,将不胜感激。
谢谢!
解决方案
您可以将简单的子类化并在完整的字段中添加字段。
class ProductSimplifiedSerializer(serializers.ModelSerializer):
subscribed = serializers.SerializerMethodField()
class Meta:
model = Product
fields = [
'id',
'name',
'subscribed'
]
def get_subscribed(self, product: Product):
return product.is_user_subscribed(self.context['request'].user)
class ProductSerializer(ProductSimplifiedSerializer):
other_field = serializers.SerializerMethodField()
class Meta(ProductSimplifiedSerializer.Meta):
fields = ProductSimplifiedSerializer.Meta.fields + [
'other_field',
'x',
'y',
'z'
]
这里的诀窍是你也可以子类化这个Meta
类。您在 Meta 子类中定义的任何属性都将覆盖父属性,因此您必须手动使用父属性。
推荐阅读
- mysql - MySQL SELECT 查询有时会获取陈旧数据
- ansible - Ansible 正在跳过调试行
- hibernate - Spring Data JPA如何在插入前忽略选择表
- git - 在 git clone 接收“缓存条目具有空 sha1 值”
- java - 从 excel 读取数据时出错,我试图从头开始设置关键字驱动的框架,未完成但现在出现 wn 错误
- apache-spark-sql - java中的Spark Dataframe sql - 如何转义单引号
- c# - 如何在 SQL Server 的外键中增加 id
- beaker-testing - 安装烧杯服务器
- ios - 如何使用 Eureka 表单从更改文本字段的行中检索值?
- html - 下拉项宽度