我有一个ListCreateAPIView
用于显示联系人列表,以及创建使用此序列化程序的新联系人:
class ContactPostSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
exclude = ('id',)
对于POST
新记录,我必须明确排除id
,以便DRF不会抱怨空id
。但是,为了使用此序列化程序列出记录,序列化程序不会返回ForeignKey
字段中的对象。要获取这些对象,我添加depth = 2
。所以现在序列化器看起来像这样:
class ContactPostSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
exclude = ('id',)
depth = 2
但是,现在,使用depth = 2
,我再也无法POST
了。它再次抱怨null id值。
编辑:我应该补充一点,我提出的错误depth=2
特定于外键对象的模型,而不是我正在创建的新记录。
我在这里缺少什么?
答案 0 :(得分:0)
我发现问题是当序列化程序有depth=2
时该部分不可写。这就是它失败的原因。另一件事是我不想更改我的URL,因此我只有/contacts/
列表和创建。要做到这一点,我必须调整我的课程来处理答案。
以下是我提出的建议:
class ContactViewSet(viewsets.ModelViewSet):
queryset = Contact.objects.all()
serializer_class = ContactSerializer
def create(self, request, *args, **kwargs):
# If we're creating (POST) then we switch serializers to the one that doesn't include depth = 2
serializer = ContactCreateSerializer(data = request.data)
if serializer.is_valid():
self.object = serializer.save()
headers = self.get_success_headers(serializer.data)
# Here we serialize the object with the proper depth = 2
new_c = ContactSerializer(self.object)
return Response(new_c.data, status = status.HTTP_201_CREATED, headers = headers)
return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)
class ContactCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
exclude = ()
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
exclude = ()
depth = 2
相信这个SO答案帮我解决了问题:https://stackoverflow.com/a/26741062/717682
答案 1 :(得分:0)
比方说,调用您的视图的链接是/ example /。
如果要发布数据,则可以这样称呼:“ / example /”,
如果要获取数据(具有深度),可以这样称呼:“ / example /?depth =” yes“
您必须有两个串行器。一种带有深度,一种没有深度。
class ContactPOSTSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
exclude = ('id',)
class ContactGETSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
exclude = ('id',)
depth = 2
因此,您的视图将是这样的:
class ExampleView(viewsets.ModelViewSet):
serializer_class = ContactPOSTSerializer
def list(self, request, *args, **kwargs):
depth = self.request.query_params.get('depth', "")
if (depth != "" and depth != "null"):
serializer = ContactGETSerializer(context={'request': request})
return Response(serializer.data)
serializer = ContactPOSTSerializer(context={'request': request})
return Response(serializer.data)
这可能不是最佳解决方案,但对我有用:)