我正在寻找一种创建嵌套序列化程序的方法,在编写或读取时行为会有所不同。在我的具体情况下,我有一些看起来像这样的模型:
class Frame(models.Model):
frame_stack = models.IntegerField()
frame_reach = models.IntegerField()
# ...
class CustomBicycle(models.Model):
frame = models.ForeignKey(Frame)
# ...
当CustomBicycle模型被序列化时,我希望它看起来像这样:
{
"id": 1,
"frame": {
"id": 1,
"frame_stack": 123,
"frame_reach": 234
}
}
假设我想提交一些要反序列化的JSON,以便更新上面的CustomBicycle实例。在这种情况下,我想提交以下JSON,以便将其Frame更新为id = 2的那个:
{
"id": 1,
"frame": {
"id": 2,
"frame_stack": 345,
"frame_reach": 456
}
}
我需要的序列化程序将查看JSON中的“frame.id”属性,然后将CustomBicycle实例更新为指向第2帧。它会忽略JSON中“frame”键下的所有其他属性(但它应该允许那些属性存在)。
我想要这个的原因是我在我的应用程序的Javascript中有类似于模型类的东西。我可以轻松地将这些Javascript模型实例序列化为类似于上面的JSON。我不想按照当前版本的Django Rest Framework的要求,以使用平面JSON API所需的方式编写额外的逻辑来序列化模型数据。
有什么想法吗?
答案 0 :(得分:0)
这是我对这个问题的一种黑客解决方案:
class NestedForeignKeyAssignmentMixin(object):
def field_from_native(self, data, files, field_name, into):
if self.read_only:
return
value = data.get(field_name)
id = value.get('id') if value else None
if not id:
if self.required:
raise ValidationError(self.error_messages['required'])
into[field_name] = None
return
model = self.Meta.model
try:
into[field_name] = model._default_manager.get(id=id)
except model.DoesNotExist:
raise ValidationError('{name} with id `{id}` does not exist'.format(
name=model.__name__,
id=id,
))
class FrameSerializer(NestedForeignKeyAssignmentMixin, serializers.ModelSerializer):
# ...
class Meta:
model = Frame
class CustomBicycleSerializer(serializers.ModelSerializer):
frame = FrameSerializer()
# ...