我正在研究Django REST框架API,并且在使用Serializers时遇到了一些问题。我会尝试稍微分离一下这个问题。基本上有Room
和Location
模型。
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请求?
答案 0 :(得分:2)
(我正在将quik_silv
评论移到答案中)
您应该使用DRF提供的SlugRelatedField:http://www.django-rest-framework.org/api-guide/relations/#slugrelatedfield
在这种情况下,您只需添加一个字段,如:location = serializers.SlugRelatedField(slug_field='name', read_only=True)
。请注意参数read_only
的使用,这应该可以解决创建模型实例时的问题。
答案 1 :(得分:0)
您应该尝试使用自定义的UUID相关字段。您可以找到示例here。
答案 2 :(得分:0)
我知道已经很长时间了,您可能已经找到了解决方案。但是我在这里发布了解决方案。阅读了一些文档之后,我遇到了一个名为to_representation()
的方法。我使用此方法将以主键形式返回的数据转换为任何其他形式。您可以在文档here中参考此方法。