Mat*_*att 6 django django-rest-framework
我有一个像这样的模型:
class MyModel(models.Model):
thing = models.ForeignKey('Thing')
Run Code Online (Sandbox Code Playgroud)
序列化器和ViewSet如下所示:
class ThingSerializer(serializers.ModelSerializer):
class Meta:
model = Thing
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
class MyModelViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
Run Code Online (Sandbox Code Playgroud)
对于MyModel列表端点,DRF返回以下对象:
[
{ id: 1, thing: 1 },
{ id: 2, thing: 1 },
{ id: 3, thing: 2 },
{ id: 4, thing: 4 }
]
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉DRF 在仅是ID而非实际相关对象的ForeignKey字段的末尾自动包含“ _id”?例如
[
{ id: 1, thing_id: 1 },
{ id: 2, thing_id: 1 },
{ id: 3, thing_id: 2 },
{ id: 4, thing_id: 4 }
]
Run Code Online (Sandbox Code Playgroud)
在这里找到了相同的请求和解决方案:
https://github.com/tomchristie/django-rest-framework/issues/3121
https://gist.github.com/ostcar/eb78515a41ab41d1755b
在AppendIdSerializerMixin.get_fields对JSON的输出改写就足够了对象(与_id追加),但写回API时,这是一个有点复杂,它在逻辑IdPrimaryKeyRelatedField和IdManyRelatedField句柄。
class IdManyRelatedField(relations.ManyRelatedField):
field_name_suffix = '_ids'
def bind(self, field_name, parent):
self.source = field_name[:-len(self.field_name_suffix)]
super(IdManyRelatedField, self).bind(field_name, parent)
class IdPrimaryKeyRelatedField(relations.PrimaryKeyRelatedField):
"""
Field that the field name to FIELD_NAME_id.
Only works together the our ModelSerializer.
"""
many_related_field_class = IdManyRelatedField
field_name_suffix = '_id'
def bind(self, field_name, parent):
"""
Called when the field is bound to the serializer.
Changes the source so that the original field name is used (removes
the _id suffix).
"""
if field_name:
self.source = field_name[:-len(self.field_name_suffix)]
super(IdPrimaryKeyRelatedField, self).bind(field_name, parent)
class AppendIdSerializerMixin(object):
'''
Append '_id' to FK field names
https://gist.github.com/ostcar/eb78515a41ab41d1755b
'''
serializer_related_field = IdPrimaryKeyRelatedField
def get_fields(self):
fields = super(AppendIdSerializerMixin, self).get_fields()
new_fields = type(fields)()
for field_name, field in fields.items():
if getattr(field, 'field_name_suffix', None):
field_name += field.field_name_suffix
new_fields[field_name] = field
return new_fields
class MyModelSerializer(AppendIdSerializerMixin, serializers.ModelSerializer):
class Meta:
model = MyModel
class MyModelViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
Run Code Online (Sandbox Code Playgroud)