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

时间:2016-06-18 16:06:18

标签: django django-rest-framework

我有一个这样的模型:

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

Serializers和ViewSet如下:

[ 
    { id: 1, thing: 1 },
    { id: 2, thing: 1 },
    { id: 3, thing: 2 },
    { id: 4, thing: 4 }
]

对于MyModel列表端点,DRF返回对象,如:

[ 
    { id: 1, thing_id: 1 },
    { id: 2, thing_id: 1 },
    { id: 3, thing_id: 2 },
    { id: 4, thing_id: 4 }
]

有没有办法告诉DRF 自动在ForeignKey字段的末尾包含“_id”只是ID而不是实际的相关对象? e.g。

{ where 'classroom_id = ?' % room_id }

4 个答案:

答案 0 :(得分:4)

在此处找到相同的请求和解决方案:

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

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

覆盖足以输出JSON对象(附加了_id),但在写回API时,它更复杂一些,AppendIdSerializerMixin.get_fieldsIdPrimaryKeyRelatedField中的逻辑处理这一点。

IdManyRelatedField

答案 1 :(得分:0)

ok matt只需将该参数添加到模型类中:

d <- structure(list(ID = 1:3, response = c("BCCAD", "ABCCD", "BA.DC")), .Names = c("ID", "response"), class = "data.frame", row.names = c(NA, -3L))

答案 2 :(得分:0)

它似乎相当复杂,因为它不是DRF允许配置的东西。但是像往常一样,你可以覆盖一切。

似乎所有内容都发生在model_meta.py文件中。在此文件中,您可以替换

forward_relations[field.name] = RelationInfo(

通过

forward_relations[field.name + '_id'] = RelationInfo(

小心,您需要在该功能中执行两次。

完成后,您仍然需要做,因为ModelSeralizer取决于真实的 model_meta。您似乎需要替换这三行:

然后,您需要实施覆盖MyModelSerializer的{​​{1}}和三种方法:ModelSerializercreateget_fields。我在get_unique_together_validators请求上对其进行了测试,结果正常。

正如您所看到的,这是一个大量的代码重写,这意味着维护升级的困难。 然后,我强烈建议您在此之前再三考虑。与此同时,您仍然可以在DRF项目上打开一个问题,使其更具可配置性(并且可维护)。

答案 3 :(得分:0)

您可以在model

中使用db_column模型字段选项
class MyModel(models.Model):
    thing = models.ForeignKey('Thing', db_column='thing_id')

或者如果您不想更改模型,可以通过更改serializer中的source序列化程序字段来实现:

class ThingSerializer(serializers.ModelSerializer):
    thing_id = serializers.IntegerField(source='thing')
    class Meta:
        model = Thing
        fields = ('thing_id','other_field', 'another_field')