【发布时间】:2016-12-29 09:19:00
【问题描述】:
所以我尝试通过django-rest-framework (DRF) 创建一个可浏览的 API,但我在嵌套序列化程序时遇到了一些问题。到目前为止,我可以将Sport 和Category 字段/外键包含到我的Article 中,但是当我尝试通过API 使用POST 时,我收到如下错误消息:
拨打
Article.objects.create()时收到TypeError。这可能是因为您在序列化程序类上有一个可写字段,它不是Article.objects.create()的有效参数。您可能需要将该字段设为只读,或重写 ArticleSerializer.create() 方法以正确处理此问题。 原始异常文本是:int() 参数必须是字符串、类似字节的对象或数字,而不是“ArticleSport”。
这是我的文件:
models.py
[...]
class ArticleSport(TimeStampedModel):
title = models.CharField(max_length=20, blank=False)
slug = AutoSlugField(populate_from='title', unique=True, always_update=True)
parent = models.ForeignKey('self', blank=True, null=True, related_name='children') # TODO: Add on_delete?
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
def __str__(self):
return '{0}'.format(self.title)
#class Meta: # TODO: Migrate live
#unique_together = ('title', 'parent')
class ArticleCategory(TimeStampedModel):
title = models.CharField(max_length=20, blank=False)
slug = AutoSlugField(populate_from='title', unique=True, always_update=True)
parent = models.ForeignKey('self', blank=True, null=True, related_name='children') # TODO: Add on_delete?
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
def __str__(self):
return '{0}'.format(self.title)
class Meta:
verbose_name_plural = 'article categories'
#unique_together = ('title', 'parent') # TODO: Migrate live
class Article(TimeStampedModel):
DEFAULT_FEATURED_IMAGE = settings.STATIC_URL + 'images/defaults/default-featured-image.png'
title = models.CharField(max_length=160, blank=False)
slug = AutoSlugField(populate_from='title', unique=True, always_update=True)
sport = models.ForeignKey(ArticleSport, on_delete=models.CASCADE, related_name='articleAsArticleSport')
category = models.ForeignKey(ArticleCategory, on_delete=models.CASCADE, related_name='articleAsArticleCategory')
featured_image = models.ImageField(upload_to=PathAndUniqueFilename('featured-images/'), blank=True)
featured_image_caption = models.CharField(max_length=100, blank=True)
views = models.IntegerField(default=0)
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
def get_absolute_url(self):
return reverse('main:article_specific', args=[self.slug]) # TODO: Remove if standalone pages are removed
def get_featured_image(self):
if self.featured_image:
return self.featured_image.url
else:
return self.DEFAULT_FEATURED_IMAGE
def get_comment_count(self):
return ArticleComment.objects.filter(article=self).count()
def __str__(self):
return '{0}'.format(self.title)
[...]
urls.py
[...]
class ArticleSportSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ArticleSport
fields = ('id', 'title', 'parent', 'created', 'modified')
class ArticleCategorySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ArticleCategory
fields = ('id', 'title', 'parent', 'created', 'modified')
class ArticleSerializer(serializers.HyperlinkedModelSerializer):
sport = ArticleSportSerializer(read_only=True)
sport_id = serializers.PrimaryKeyRelatedField(queryset=ArticleSport.objects.all(), write_only=True)
category = ArticleCategorySerializer(read_only=True)
category_id = serializers.PrimaryKeyRelatedField(queryset=ArticleCategory.objects.all(), write_only=True)
modified = serializers.HiddenField(default=timezone.now()) #TODO: Figure out how to implement this
class Meta:
model = Article
fields = ('id', 'title', 'sport', 'sport_id', 'category', 'category_id', 'featured_image', 'featured_image_caption', 'views', 'created', 'modified')
[...]
到 API 的示例 POST:
{
"title": "This is a test Title",
"sport_id": 1,
"category_id": 1,
"featured_image": null,
"featured_image_caption": "",
"views": null,
"modified": null
}
【问题讨论】:
-
为什么不发送主键而不是整个模型?
-
我对 DRF 很陌生,我将如何处理您的建议?
标签: python django api post django-rest-framework