2016-04-22 3459 views
1

后,我公司目前有以下视图集:Django的REST框架perform_create:你不能调用`.save()``访问serializer.data`

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对象。有什么我错过,会导致此编辑?我该如何解决这个错误?

+1

我很少需要在视图中使用方法重写,当我需要重写代码时,它通常会以黑客和原始重写代码的形式复制粘贴。尽可能在串行器上实现东西通常会更好。是不是可以把你的东西放到串行器的'create()'方法中? – pasztorpisti

+0

我同意我应该重新调查我是如何做到这一点的。不过,我仍然觉得这可能是问题的表现。我直接从DRF的文档中获取了该代码。 –

回答

2

您根本不需要拨打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源代码,看看它在做什么。它写得很好,很清楚。

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

+0

删除is_valid仍会产生相同的错误,但是,阻止我执行您在第二个示例中所做的操作。我最终想添加到连接表中,但我想首先需要解决这个问题。感谢您对嵌套可写序列化器的更多评论;我会调查。 –

+0

可写的嵌套表示正是我所需要的。感谢您的评论。但是,我仍然觉得原来的问题可能是问题的表现。我直接从DRF的文档中获取了该代码。 –

+0

@KerryRitter通常在序列化程序的'create()'和/或'update()'中,必须使用自定义代码来处理可写的嵌套表示:http://www.django-rest-framework.org/api-guide/关系/#可写嵌套序列化器 – pasztorpisti