我已成功使用django类创建了序列化器类,并且它仅对GET
方法非常有效,但我也需要POST
方法才能工作。
当前Post方法不起作用...
这是我的序列化器类:
from rest_framework import serializers
from . models import Author, Article, Category, Organization
class OrganizationSerializer(serializers.ModelSerializer):
class Meta:
model = Organization
fields = '__all__'
class AuthorSerializer(serializers.ModelSerializer):
organization = OrganizationSerializer()
class Meta:
model = Author
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = '__all__'
class ArticleSerializer(serializers.ModelSerializer):
author = AuthorSerializer()
category = CategorySerializer()
class Meta:
model = Article
fields = '__all__'
以上代码段仅适用于GET方法,不适用于POST方法...
我需要它应该适用于post方法。
如果您不了解上述序列化工具,则可以查看我的模型:
from django.db import models
import uuid
class Organization(models.Model):
organization_name = models.CharField(max_length=50)
contact = models.CharField(max_length=12, unique=True)
def __str__(self):
return self.organization_name
class Author(models.Model):
name = models.CharField(max_length=40)
detail = models.TextField()
organization = models.ForeignKey(Organization, on_delete=models.DO_NOTHING)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Article(models.Model):
alias = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='author')
title = models.CharField(max_length=200)
body = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
任何人都可以告诉我,使我的端点适用于post方法吗?
这是我看到的错误,来自终端:
File "/home/pyking/.local/lib/python3.6/site-packages/rest_framework/serializers.py", line 823, in raise_errors_on_nested_writes
class_name=serializer.__class__.__name__
AssertionError: The `.create()` method does not support writable nested fields by default.
Write an explicit `.create()` method for serializer `blog2.serializers.ArticleSerializer`, or set `read_only=True` on nested serializer fields.
[23/Jun/2019 12:22:49] "POST /blog2/api/v1/article HTTP/1.1" 500 122369
Not Found: /favicon.ico
[23/Jun/2019 12:22:49] "GET /favicon.ico HTTP/1.1" 404 2186
答案 0 :(得分:0)
正如错误stacktrace所说,您应该在序列化器类中实现create()
。在DRF中处理嵌套序列化是很常见的情况。
此问题的一种解决方案是为读取和写入数据定义不同的序列化器。这意味着一个用于获取资源的串行器和一个用于创建/更新资源的串行器。
首先,定义用于标准书写操作( POST / PUT / PATCH )的ModelSerializer
:< / p>
class ArticleSerializer(serializers.ModelSerializer):
# Important: Remove your nested serializers declaration here!
class Meta:
model = Article
fields = '__all__'
然后扩展此序列化程序,并使用嵌套序列化( GET )覆盖要获取的字段:
class ArticleReadSerializer(ArticleSerializer):
author = AuthorSerializer(read_only=True)
category = CategorySerializer(read_only=True)
# Note the read_only=True parameters in both serializers
# And the class you inherit from
然后通过覆盖get_serializer_class
为APIView
/ ViewSet
指定要用于不同操作的序列化器:
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
def get_serializer_class(self):
if self.request.method in ['GET']:
return ArticleReadSerializer
return ArticleSerializer
这是ModelViewSet
的示例,但是DRF的每个通用视图类中都存在此方法,因此它是可转移的机制。
现在,您可以通过使用主键指定相关模型来创建文章:
{
"title": "...",
"author": 1,
"category": 1
}
注意:您还应该在organization = OrganizationSerializer(read_only=True)
中设置AuthorSerializer
,因为您已经创建了具有相关组织的作者,并且在创建文章时不要创建新的组织条目