Django REST Framework perform_create:访问`serializer.data`后不能调用`.save()`

时间:2016-04-22 01:23:44

标签: django django-rest-framework

我目前有以下视图集:

class ArtistProfileViewSet(viewsets.ModelViewSet):
    queryset = ArtistProfile.objects.all()
    serializer_class = ArtistProfileSerializer

    def perform_create(self, serializer):
        if serializer.is_valid():
            serializer.save()

使用以下序列化程序:

class SimpleArtistTrackSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = ArtistTrack
        fields = (...my fields...)


class ArtistProfileSerializer(serializers.HyperlinkedModelSerializer):
    owners = UserSerializer(many=True, required=False)
    tracks = SimpleArtistTrackSerializer(many=True, required=False)

    class Meta:
        model = ArtistProfile
        fields = (...my fields...)

我收到以下错误:

AssertionError: You cannot call `.save()` after accessing `serializer.data`.If you need to access data before committing to the database then inspect 'serializer.validated_data' instead. 

我没有看到我在哪里编辑serializer.data对象。我有什么遗失会导致这种编辑吗?如何解决此错误?

3 个答案:

答案 0 :(得分:3)

您根本不需要在那里拨打is_valid。进行更新时,序列化程序将使用模型实例进行初始化(基于路径中的pk,例如PATCH /artists/{3}/)。如果要将数据传递给序列化程序,则可以调用is_valid(),如下所示:

ser = MySerializer(data=request.data) # validate incoming post, etc
ser.is_valid(raise_exceptions=True)
data = ser.validated_data

要在保存时向序列化程序发送其他数据(例如设置公司或设置用户等),请使用如下覆盖:

def perform_create(self, serializer):
    serializer.save(company=self.request.user.company)

有关更多详细信息,我将浏览DRF源代码并查看它正在执行的操作。它写得很清楚。

您的评论表明另一个问题很多更大。您说您想要在艺术家和用户之间的“加入”表中添加其他数据。这可以完成,但是完全不同的主题,您最终手动管理关系。另外,阅读嵌套的可写序列化器,这是一个很大的主题,甚至更多的手工劳动。

答案 1 :(得分:1)

如果您使用的是PyCharm,并且正在调试一些代码,请检查手表中是否没有调用serializer.data。每当调试器在上下文中出现给定的序列化程序时,它都会调用.data,即使您没有在代码中显式调用它。

答案 2 :(得分:0)

以与“监视”(如果要进行调试)相同的方式,尝试通过'data'行之前不要检查(或扩展)serializer的{​​{1}}字段。 / p>