我在DRF中有一个序列化程序类,如下所示:
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
created_by = UserSerializer() # created_by is an FK to User model
class Meta:
model = Project
fields = ('id', 'title', 'created_by')
我的观点:
class ProjectList(generics.ListCreateAPIView):
model = Project
serializer_class = ProjectSerializer
filter_fields = ('title',)
def post(self, request, format=None):
serializer = ProjectSerializer(data={
"id": 12,
"title": "FooBar's Project",
"created_by": {
"id": 1,
"username": "foobar",
"first_name": "foo",
"last_name": "bar",
},
})
if serializer.is_valid():
serializer.save()
else:
print serializer.errors
return Response(serializer.data, status=status.HTTP_201_CREATED)
除了DRF抱怨:
之外,这几乎与预期一样{'created_by': [{'username': [u'User with this Username already exists.']}]}
我想要的是项目是参考现有用户创建的。我在这里做错了什么?
注意:我正在追踪DRF的干线,而不是来自奶酪店。
答案 0 :(得分:6)
如果要分配现有用户而不是创建一个用户,则嵌套序列化程序不是这样。由于您只想将关系添加到用户,您需要查看关系。
PrimaryKeyRelatedField
是可行的方法,因为此字段可写,您还需要传递queryset
属性。
created_by = serializers.PrimaryKeyRelatedField(queryset=User.objects.all())
请参阅文档以检查可传递给此字段的其他选项:
http://django-rest-framework.org/api-guide/relations#primarykeyrelatedfield
然后您的示例帖子可能如下所示:
def post(self, request, format=None):
user = User.objects.get(pk=8)
serializer = ProjectSerializer(data={
"id": 12,
"title": "FooBar's Project",
"created_by": user.pk,
})
答案 1 :(得分:0)
(代表问题作者发布)。
这是可行的解决方案:
# serializers.py
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
...
created_by = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all()
)
class Meta:
model = Project
fields = ('id', 'title', 'created_by')
# views.py
class ProjectList(generics.ListCreateAPIView):
model = Project
serializer_class = ProjectSerializer
filter_fields = ('title',)
def post(self, request, format=None):
serializer = ProjectSerializer(data={
"title": request.DATA.get('title'),
"created_by": request.user.pk,
})
if serializer.is_valid():
serializer.save()
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
return Response(serializer.data, status=status.HTTP_201_CREATED)