Django Rest Framework 序列化程序 create() 不会被触发
Django Rest Framework serializer create() doesn't get triggered
我有以下序列化器
class MyModelSerializer(serializers.ModelSerializer):
user = UserSerializer()
def create(self, validated_data):
print("TEST")
MyModel, created = MyModel.objects.get_or_create(**validated_data)
return MyModel
class Meta:
model = MyModel
fields = ('pk', 'title', 'user', 'movie', 'timestamp', 'text',)
和以下视图集:
class MyModelViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
当我向指定视图集对应的端点发出 POST
请求时,create()
方法什么都不做。如您所见,我尝试在控制台 TEST
中打印出来,但什么也没有。
有人知道这种奇怪的行为吗?
提前致谢!
编辑:
API 通话:
return axios({
method: 'post',
url: 'http://localhost:8000/api/mymodel/',
data: {
title: this.title,
movie: this.id,
text: this.text,
user: this.user
}
这可能是因为您进行了某种错误处理,因为您编写 def create 函数的方式会引发错误。我测试了下面的代码,它对我有用,试一试:
class MyModelSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = MyModel
fields = ('pk', 'title', 'user', 'movie', 'timestamp', 'text',)
def create(self, validated_data):
print("TEST")
data = validated_data
data, created = MyModel.objects.get_or_create(**data)
return data
希望对您有所帮助!
如果查看 ViewSet 中 POST 处理的实现,您会发现:
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
您的 create
方法在序列化器验证数据后被调用。
您看到的错误(用户已存在)是从上面的代码片段调用 serializer.is_valid
的结果。
因此,它永远无法调用您的 create
。您的创建将作为上述代码段 self.perform_create()
的一部分被调用。
所以这意味着您正在尝试创建一个已经存在的用户。所以在你的模型中你有唯一的用户名。
好的。我找到了一个替代方案。因为我只想要用户对象的用户名,所以我删除了 user = UserSerializer()
并添加了 user_username = serializers.ReadOnlyField(source='user.username')
:
class ReviewSerializer(serializers.ModelSerializer):
user_username = serializers.ReadOnlyField(source='user.username')
class Meta:
model = Review
fields = ('pk', 'title', 'user', 'user_username', 'movie', 'timestamp', 'review_text',)
user = UserSerializer()
让我很头疼,所以我绕开了它。我将检查 Entushiast Martin 的答案作为解决方案,因为他们促使我找到了实际答案。谢谢。
已解决。
我有以下序列化器
class MyModelSerializer(serializers.ModelSerializer):
user = UserSerializer()
def create(self, validated_data):
print("TEST")
MyModel, created = MyModel.objects.get_or_create(**validated_data)
return MyModel
class Meta:
model = MyModel
fields = ('pk', 'title', 'user', 'movie', 'timestamp', 'text',)
和以下视图集:
class MyModelViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
当我向指定视图集对应的端点发出 POST
请求时,create()
方法什么都不做。如您所见,我尝试在控制台 TEST
中打印出来,但什么也没有。
有人知道这种奇怪的行为吗?
提前致谢!
编辑: API 通话:
return axios({
method: 'post',
url: 'http://localhost:8000/api/mymodel/',
data: {
title: this.title,
movie: this.id,
text: this.text,
user: this.user
}
这可能是因为您进行了某种错误处理,因为您编写 def create 函数的方式会引发错误。我测试了下面的代码,它对我有用,试一试:
class MyModelSerializer(serializers.ModelSerializer):
user = UserSerializer()
class Meta:
model = MyModel
fields = ('pk', 'title', 'user', 'movie', 'timestamp', 'text',)
def create(self, validated_data):
print("TEST")
data = validated_data
data, created = MyModel.objects.get_or_create(**data)
return data
希望对您有所帮助!
如果查看 ViewSet 中 POST 处理的实现,您会发现:
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
您的 create
方法在序列化器验证数据后被调用。
您看到的错误(用户已存在)是从上面的代码片段调用 serializer.is_valid
的结果。
因此,它永远无法调用您的 create
。您的创建将作为上述代码段 self.perform_create()
的一部分被调用。
所以这意味着您正在尝试创建一个已经存在的用户。所以在你的模型中你有唯一的用户名。
好的。我找到了一个替代方案。因为我只想要用户对象的用户名,所以我删除了 user = UserSerializer()
并添加了 user_username = serializers.ReadOnlyField(source='user.username')
:
class ReviewSerializer(serializers.ModelSerializer):
user_username = serializers.ReadOnlyField(source='user.username')
class Meta:
model = Review
fields = ('pk', 'title', 'user', 'user_username', 'movie', 'timestamp', 'review_text',)
user = UserSerializer()
让我很头疼,所以我绕开了它。我将检查 Entushiast Martin 的答案作为解决方案,因为他们促使我找到了实际答案。谢谢。
已解决。