gpt4 book ai didi

python - 如何在 django-rest-framework POST 中包含 ForeignKey

转载 作者:太空宇宙 更新时间:2023-11-04 03:07:11 29 4
gpt4 key购买 nike

所以我尝试通过 django-rest-framework (DRF) 制作一个可浏览的 API,但我在嵌套序列化器时遇到了一些问题。到目前为止,我能够将 SportCategory 字段/外键包含到我的 Article 中,但是当我尝试 POST 通过 API,我收到如下错误消息:

Got a TypeError when calling Article.objects.create(). This may be because you have a writable field on the serializer class that is not a valid argument to Article.objects.create(). You may need to make the field read-only, or override the ArticleSerializer.create() method to handle this correctly. Original exception text was: int() argument must be a string, a bytes-like object or a number, not 'ArticleSport'.

这是我的文件:

模型.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')

[...]

示例 POST 到 API:

{
"title": "This is a test Title",
"sport_id": 1,
"category_id": 1,
"featured_image": null,
"featured_image_caption": "",
"views": null,
"modified": null
}

最佳答案

所以我能够使用一些 Carter_Smith 来回答这个问题的建议 - 我不是 100% 确定为什么这样做有效,但我添加了这个 create()我的方法 ArticleSerializer , 它起作用了:

def create(self, validated_data):
# Override default `.create()` method in order to properly add `sport` and `category` into the model
sport = validated_data.pop('sport_id')
category = validated_data.pop('category_id')
article = Article.objects.create(sport=sport, category=category, **validated_data)
return article

我的猜测是 PrimaryKeyRelatedField()试图解决 sport_idcategory_id作为基于名称的 kwarg 字段,当它们应该只是 sport 时和 category ,所以压倒一切.create()允许您修复该问题,同时仍允许 read_only sport 的字段和 category .希望这对遇到同样问题的其他人有所帮助。

关于python - 如何在 django-rest-framework POST 中包含 ForeignKey,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39086026/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com