django REST框架多源字段 [英] django REST framework multi source field
本文介绍了django REST框架多源字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
比方说,我的models.py中有这些:
Let's say that I have these in my 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中使用主题。
为此,我需要对其进行序列化:
And I want to use Theme in my api.
To do so, I need to serialize it:
#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")
不幸的是,我不能使用 level_set 源,因为它不存在。
如何将 puzzlelevel_set 和 imageandwordlevel_set 组合到单个 levels 字段中?
Unfortunaly, I can't use the level_set source as it doesn't exist.
How could I combine puzzlelevel_set and imageandwordlevel_set in a single levels field ?
推荐答案
实际上,在深入研究REST框架的源代码之后,我想到了一个解决方案:
我写了一个能够管理多个源的自定义字段。
Actually, after some digging into REST framework's source code, I came into a solution :
I wrote a custom field able to manage multiple sources.
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
现在,我的主题序列化器如下所示:
Now, my theme serializer looks like this :
class ThemeSerializer(serializers.ModelSerializer):
levels = MultiSourceField(source=[
PuzzleLevelSerializer(source="puzzlelevel_set"),
ImageAndWordLevelSerializer(source="imageandwordlevel_set")
])
class Meta:
model = Theme
fields = ("offset", "finished", "levels",)
这篇关于django REST框架多源字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文