django-rest-framework多对多关系。如果不存在则创建

时间:2015-02-02 09:16:22

标签: python django django-rest-framework

我尝试将以下数据发送到我的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

1 个答案:

答案 0 :(得分:3)

Hashtags不是字符串,而是该示例中的dict。你必须提交:

{
    "hashtags": [{"hashtag": "hashtag"}], 
    "title": "title", 
    "message": "message"
}