我在通过ID创建具有OneToOneField引用的对象时遇到了一些问题。我的代码示例:
models.py
class Person(models.Model):
name = models.CharField(length=50)
class ExtraInfo(models.Model):
person = models.OneToOneField(
Person,
related_name='+',
primary_key=True,
on_delete=models.CASCADE
)
info = models.CharField(length=50)
serializers.py
class ExtraInfoSerializer(serializers.ModelSerializer):
class Meta:
model = models.ExtraInfo
views.py
class ExtraInfoView(viewsets.ModelViewSet):
queryset = models.ExtraInfo.objects.all()
serializer_class = serializers.ExtraInfoSerializer
urls.py
...
api_router = DefaultRouter()
api_router.register(r'extrainfo', ExtraInfoView)
url_patterns = [
url(r'/', include(api_router.urls))
]
...
现在,无论何时我做GET / extrainfo /我都会得到以下内容:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"person": 1,
"info": "foo"
},
{
"person": 2,
"info": "bar"
}
]
}
所以这一切都很好 - 正是我所期待的。当我尝试创建一些ExtraInfo时出现问题,当我使用诸如以下的正文POST到/ extrainfo /时:
{
"person": 3,
"info": "blah"
}
我收到以下错误:
ValueError: Cannot assign "3": "ExtraInfo.person" must be a "Person" instance.
所以我理解它的含义 - 如果我在定制的代码中这样做,我会想做像ExtraInfo.objects.create(person_id = 3,info =“blah”)这样的事情。我只是无法弄清楚如何让它像我想要的那样。
我看一下this answer,我无法弄清楚我哪里出错了。我似乎可以通过将它添加到我的序列化器来解决它:
def create(self, validated_data):
validated_data['person_id'] = validated_data['person']
del validated_data['person']
return super(ExtraInfoSerializer, self).create(validated_data)
但这似乎不是最好的方法。我觉得我要么错过了一些小的东西,要么基本上误解了一些东西,但无论哪种方式我都觉得奇怪的是它将序列化为GET的主键但不会在POST中使用它。任何帮助将不胜感激。
答案 0 :(得分:0)
序列化程序期望person
成为模型实例,因此您可以这样做:
{
"person": Person.objects.get(pk=3),
"info": "blah"
}
在视图中,您将获得相关模型实例的第一个表示形式,这是其主键。您还可以通过在序列化程序中指定depth参数来获取完整的模型实例。像:
class ExtraInfoSerializer(serializers.ModelSerializer):
class Meta:
model = models.ExtraInfo
depth = 1