将序列化器字段显示为'命名为'字段而不是主键字段

时间:2014-09-03 08:09:34

标签: django django-rest-framework

我正在研究Django REST框架API,并且在使用Serializers时遇到了一些问题。我会尝试稍微分离一下这个问题。基本上有RoomLocation模型。

class Room(models.Model):
    uuid = UUIDField(primary_key=True)
    ...
    location = models.ForeignKey(Location, related_name='room')
    ...
class Location(models.Model):
    uuid = UUIDField(primary_key=True)
    name = models.CharField(max_length=255)
    def __unicode__(self):
        return unicode(self.name)

和相应的序列化程序,

class RoomSerializer(serializers.ModelSerializer):
    location = serializers.RelatedField()
    class Meta:
        model = Room
        fields = ('uuid', 'location')
class LocationSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Location
        fields = ('uuid', 'name')

我已经探索了将uuid的显示更改为位置名称的多种方法,包括使用serializers.SerializerMethodField()并使用上面的serializers.RelatedField(),并且它们确实有效。作为参考,请参阅下面的JSON输出。

{
    "uuid": "491ab09d-qqqq-wwww-eeee-5801dbac0fef",
    "location": "Kota Kinabalu", 
    "created": "2014-09-03T07:52:45.399Z", 
    "modified": "2014-09-03T07:52:45.530Z"
}

但是,我无法在Room上执行model.save(),因为Django或者更确切地说数据库(在我的情况下是postgresql)抱怨location_id为空。我认为这是因为当我向API端点/ api / rooms /发送POST请求时,当我修改RoomSerializer时,location_id会留空。

如果使用默认的ModelViewSet,您会看到默认表单中缺少Location字段。

如何正确使用序列化程序,以便我可以显示位置的名称(“Kota Kinabalu”而不是像6e6acbbb-xxxx-yyyy-zzzz-1cf1a5bac22c这样的uuid字符串)我仍然可以接受正确的POST请求?

3 个答案:

答案 0 :(得分:2)

(我正在将quik_silv评论移到答案中)

您应该使用DRF提供的SlugRelatedField:http://www.django-rest-framework.org/api-guide/relations/#slugrelatedfield

在这种情况下,您只需添加一个字段,如:location = serializers.SlugRela‌​tedField(slug_field='‌​name', read_only=True)。请注意参数read_only的使用,这应该可以解决创建模型实例时的问题。

答案 1 :(得分:0)

您应该尝试使用自定义的UUID相关字段。您可以找到示例here

答案 2 :(得分:0)

我知道已经很长时间了,您可能已经找到了解决方案。但是我在这里发布了解决方案。阅读了一些文档之后,我遇到了一个名为to_representation()的方法。我使用此方法将以主键形式返回的数据转换为任何其他形式。您可以在文档here中参考此方法。