Django Rest 框架 - 无法使用现有的 FK 引用创建对象



我在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的行李箱,而不是从奶酪店。

如果您想分配一个现有的用户,而不是创建一个嵌套的序列化程序。由于您只想将关系添加到用户,因此需要查看关系。

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,
    })

(代表问题作者发布)

这是有效的解决方案:

# 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)

最新更新