django-rest-framework 多对多关系。如果不存在则创建
django-rest-framework many-to-many relations. Create if not exists
我尝试将以下数据发送到我的 Django 应用程序:
{
"hashtags": ["hashtag"],
"title": "title",
"message": "message"
}
我收到了这样的回复:
{
"hashtags": [
{
"non_field_errors": [
"Invalid data. Expected a dictionary, but got int."
]
}
]
}
我在 views.py
中定义了以下视图
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = IsAuthorizedOwnerOrReadOnly,
模型定义如下:
class Post(models.Model):
ambassador = models.OneToOneField("User")
publish_date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
hashtags = models.ManyToManyField("PostHashtags", related_query_name="posts")
title = models.CharField(max_length=TEXT_SHORT, null=True, blank=True)
message = models.CharField(max_length=TEXT_MIDDLE, null=True, blank=True)
class PostHashtags(models.Model):
hashtag = models.CharField(max_length=TEXT_SHORT, null=False)
def __unicode__(self):
return self.hashtag
我这样定义序列化程序:
class PostHashtagSerializer(serializers.ModelSerializer):
class Meta:
model = PostHashtags
fields = ("hashtag",)
class PostSerializer(serializers.ModelSerializer):
hashtags = PostHashtagSerializer(many=True)
class Meta:
model = Post
fields = ("id", "hashtags", "title", "message",)
read_only_fields = ("id", 'account_name',)
主题标签似乎不是使用我当前的序列化配置自动创建的。如果我的 hashtags
尚不存在,有没有办法创建它们?如果它们存在,让 Post
使用相同的标签?在那种情况下,我的序列化程序应该如何定义?
编辑 1:
在 GwynBleidD 的建议之后,我现在收到以下错误:
The `.create()` method does not support writable nestedfields by default.
Write an explicit `.create()` method for serializer PostSerializer , or set `read_only=True` on nested serializer fields.
有人对这种创建方法有什么建议吗?
编辑 2: 使用以下序列化器解决了它
class PostHashtagSerializer(serializers.ModelSerializer):
hashtag = serializers.CharField()
class Meta:
model = PostHashtags
fields = ("hashtag",)
class PostSerializer(serializers.ModelSerializer):
hashtags = PostHashtagSerializer(many=True,)
class Meta:
model = Post
fields = ("ambassador", "hashtags", "title", "message",)
def create(self, validated_data):
hashtags_data = validated_data.pop('hashtags')
post = Post.objects.create(**validated_data)
for hashtag in hashtags_data:
ht = PostHashtags.objects.create()
ht.hashtag = hashtag.get("hashtag")
ht.save()
post.hashtags.add(ht)
post.save()
return post
在那个例子中,标签不是字符串,而是字典。您必须提交:
{
"hashtags": [{"hashtag": "hashtag"}],
"title": "title",
"message": "message"
}
我尝试将以下数据发送到我的 Django 应用程序:
{
"hashtags": ["hashtag"],
"title": "title",
"message": "message"
}
我收到了这样的回复:
{
"hashtags": [
{
"non_field_errors": [
"Invalid data. Expected a dictionary, but got int."
]
}
]
}
我在 views.py
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = IsAuthorizedOwnerOrReadOnly,
模型定义如下:
class Post(models.Model):
ambassador = models.OneToOneField("User")
publish_date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
hashtags = models.ManyToManyField("PostHashtags", related_query_name="posts")
title = models.CharField(max_length=TEXT_SHORT, null=True, blank=True)
message = models.CharField(max_length=TEXT_MIDDLE, null=True, blank=True)
class PostHashtags(models.Model):
hashtag = models.CharField(max_length=TEXT_SHORT, null=False)
def __unicode__(self):
return self.hashtag
我这样定义序列化程序:
class PostHashtagSerializer(serializers.ModelSerializer):
class Meta:
model = PostHashtags
fields = ("hashtag",)
class PostSerializer(serializers.ModelSerializer):
hashtags = PostHashtagSerializer(many=True)
class Meta:
model = Post
fields = ("id", "hashtags", "title", "message",)
read_only_fields = ("id", 'account_name',)
主题标签似乎不是使用我当前的序列化配置自动创建的。如果我的 hashtags
尚不存在,有没有办法创建它们?如果它们存在,让 Post
使用相同的标签?在那种情况下,我的序列化程序应该如何定义?
编辑 1: 在 GwynBleidD 的建议之后,我现在收到以下错误:
The `.create()` method does not support writable nestedfields by default.
Write an explicit `.create()` method for serializer PostSerializer , or set `read_only=True` on nested serializer fields.
有人对这种创建方法有什么建议吗?
编辑 2: 使用以下序列化器解决了它
class PostHashtagSerializer(serializers.ModelSerializer):
hashtag = serializers.CharField()
class Meta:
model = PostHashtags
fields = ("hashtag",)
class PostSerializer(serializers.ModelSerializer):
hashtags = PostHashtagSerializer(many=True,)
class Meta:
model = Post
fields = ("ambassador", "hashtags", "title", "message",)
def create(self, validated_data):
hashtags_data = validated_data.pop('hashtags')
post = Post.objects.create(**validated_data)
for hashtag in hashtags_data:
ht = PostHashtags.objects.create()
ht.hashtag = hashtag.get("hashtag")
ht.save()
post.hashtags.add(ht)
post.save()
return post
在那个例子中,标签不是字符串,而是字典。您必须提交:
{
"hashtags": [{"hashtag": "hashtag"}],
"title": "title",
"message": "message"
}