在Django Rest Framework中将“ _id”附加到外键字段

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)

Mat*_*att 5

在这里找到了相同的请求和解决方案:

https://github.com/tomchristie/django-rest-framework/issues/3121

https://gist.github.com/ostcar/eb78515a41ab41d1755b

AppendIdSerializerMixin.get_fields对JSON的输出改写就足够了对象(与_id追加),但写回API时,这是一个有点复杂,它在逻辑IdPrimaryKeyRelatedFieldIdManyRelatedField句柄。

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)

  • 差不多三年过去了,这仍然是最好的解决方案吗?DRF 是否采取了一些措施来克服这个解决方法? (2认同)