假设我的 models.py 中有这些:
#models.py
class Theme(models.Model):
"""An theme is an asset of multiple levels."""
adventure = models.ForeignKey(Adventure)
offset = models.PositiveSmallIntegerField()
finished = models.BooleanField(default=False)
class Level(models.Model):
"""Abstract level representation"""
theme = models.ForeignKey(Theme)
offset = models.PositiveSmallIntegerField()
finished = models.BooleanField(default=False)
class Meta:
abstract = True
class PuzzleLevel(Level):
"""A level for the Puzzle game"""
points = models.CharField(max_length=200)
image = models.ImageField()
class ImageAndWordLevel(Level):
"""A level for the ImageAndWord game"""
word = models.CharField(max_length=30)
image = models.ImageField()
我想在我的 api 中使用 Theme。
为此,我需要将其序列化:
#serializers.py
class PuzzleLevelSerializer(serializers.ModelSerializer):
image = serializers.Field(source="image.url")
class Meta:
model = PuzzleLevel
fields = ("offset", "finished", "points", "image")
class ImageAndWordLevelSerializer(serializers.ModelSerializer):
image = serializers.Field(source="image.url")
class Meta:
model = ImageAndWordLevel
fields = ("offset", "finished", "word", "image")
class ThemeSerializer(serializers.ModelSerializer):
levels = serializers.Field(source="level_set")
class Meta:
model = Theme
fields = ("offset", "finished", "levels")
不幸的是,我不能使用水平集源,因为它不存在。
我怎样才能结合谜题关卡集 and 图像和单词级别集在一个单一的levels field ?
实际上,在深入研究 REST 框架的源代码之后,我找到了一个解决方案:
我编写了一个能够管理多个源的自定义字段。
class MultiSourceField(serializers.Field):
"""
A custom field to use when you want to
join multiple sources into a single field.
Example :
my_field = MultiSourceField(source=["attr1.subattr", "attr2.subattr"])
It can also handle serializers, a small example :
rel_field = MultiSourceField(source=[Serializer(source="rel"), "attr2"])
"""
def field_to_native(self, obj, field_name):
if obj is None:
return self.empty
sources = self.source
value = []
for source in sources:
if isinstance(source, serializers.BaseSerializer):
value += source.field_to_native(obj, "")
else:
#setting self.source to source in order to use the parent method
self.source = source
value.append(super(MultiSourceField, self).field_to_native(obj,
field_name))
#reverting self.source after the parent method call
self.source = sources
return value
现在,我的主题序列化器如下所示:
class ThemeSerializer(serializers.ModelSerializer):
levels = MultiSourceField(source=[
PuzzleLevelSerializer(source="puzzlelevel_set"),
ImageAndWordLevelSerializer(source="imageandwordlevel_set")
])
class Meta:
model = Theme
fields = ("offset", "finished", "levels",)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)