Skip to main content
 首页 » 编程设计

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

2024年08月26日26daizhj

我尝试将以下数据发送到我的 Django 应用程序:

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

我得到了这样的回复:

{ 
    "hashtags": [ 
        { 
            "non_field_errors": [ 
                "Invalid data. Expected a dictionary, but got int." 
            ] 
        } 
    ] 
} 

我在 views.py

中定义了以下 View
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 使用相同的 hashtag?在那种情况下,我的序列化程序应该如何定义?

编辑 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" 
}