我想编写一个类似高音的应用程序,我想获取作者的用户名而不是作者的ID。但是现在当我创建新的Tweet时出现此错误:NOT NULL约束失败:tweets_tweet.author_id
我首先尝试在我的seriliazer中使用get_ field 方法。
这是模型:
class Tweet(models.Model):
slug = models.CharField(max_length=100, unique=True, null=True,
blank=True)
content = models.TextField(max_length=150)
datestamp = models.DateTimeField(auto_now_add=True)
nb_likes = models.PositiveIntegerField(default=0)
nb_comments = models.PositiveIntegerField(default=0)
author = models.ForeignKey(
User,
on_delete = models.CASCADE,
related_name = "tweets",
related_query_name = "post",
null=False
)
def save(self, *args, **kwargs):
self.slug = slugify(self.content[:10]) + '-' + randomString()
super(Tweet, self).save(*args, **kwargs)
这是我的序列化器:
class TweetSerializer(serializers.ModelSerializer):
author = serializers.SerializerMethodField()
def get_author(self, obj):
return obj.user.username
class Meta:
model = Tweet
fields = ["content", "author", "nb_likes", "nb_comments", "slug"]
def to_representation(self, obj):
representation = super().to_representation(obj)
if obj.nb_likes > 50:
representation['super_popular'] = True
return representation
和我的JSON看起来像:
{
"content": "blablabla",
"author_username": "valentin",
"author": 1,
"nb_likes": 0,
"nb_comments": 0,
"slug": "blablabla-2159054817"
}
答案 0 :(得分:1)
您可以看到here,SerializerMethodField
是一个只读字段。因此,您已经将author
设为只读,而您仍然希望能够使用Tweet
创建一个author
。
现在,如果您要使用username
而不是id
进行读写,并且假设username
是唯一的,那么this document会为您显示可供选择的选项相关字段:将SlugRelatedField
设置为slug_field
的{{1}}允许您将“作者”作为用户名传递,也将其作为“用户名”返回:
author
请注意,这意味着您需要更改输入的JSON,因为现在“作者”键映射到ID。
但是,如果您想使用author = SlugRelatedField(slug_field="username", queryset=User.objects.all())
作为输入并使用id
作为输出,则需要将其设置为自定义关系字段,其 representation 与< em>内部价值:
username
我在这里将class TweetAuthorField(serializers.PrimaryKeyRelatedField):
def to_representation(self, value):
return value.username
子类化,因为它已经完成了使用主键(id)将数据映射到对象的所有正确操作,因此无需重写该代码。