python - django REST framework multi source field -
python - django REST framework multi source field -
let's have these in models.py :
#models.py class theme(models.model): """an theme 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 puzzle game""" points = models.charfield(max_length=200) image = models.imagefield() class imageandwordlevel(level): """a level imageandword game""" word = models.charfield(max_length=30) image = models.imagefield()
and want utilize theme in api. so, need 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")
unfortunaly, can't utilize level_set source doesn't exist. how combine puzzlelevel_set , imageandwordlevel_set in single levels field ?
actually, after digging rest framework's source code, came solution : wrote custom field able manage multiple sources.
class multisourcefield(serializers.field): """ custom field utilize when want bring together multiple sources single field. illustration : my_field = multisourcefield(source=["attr1.subattr", "attr2.subattr"]) can handle serializers, little illustration : rel_field = multisourcefield(source=[serializer(source="rel"), "attr2"]) """ def field_to_native(self, obj, field_name): if obj none: homecoming self.empty sources = self.source value = [] source in sources: if isinstance(source, serializers.baseserializer): value += source.field_to_native(obj, "") else: #setting self.source source in order utilize parent method self.source = source value.append(super(multisourcefield, self).field_to_native(obj, field_name)) #reverting self.source after parent method phone call self.source = sources homecoming value
now, theme serializer looks :
class themeserializer(serializers.modelserializer): levels = multisourcefield(source=[ puzzlelevelserializer(source="puzzlelevel_set"), imageandwordlevelserializer(source="imageandwordlevel_set") ]) class meta: model = theme fields = ("offset", "finished", "levels",)
python django serialization field django-rest-framework
Comments
Post a Comment