我想创建一个与另一个模型(Tag)具有多对多关系的模型(Source),并创建一个Source对象,而不会在数据库中复制Tag实例。这是我的模特:
class Tag(models.Model):
name = models.CharField(max_length=50, null=False, default='source')
def __unicode__(self):
return self.name
class Source(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
language = models.CharField(max_length=50)
color = models.CharField(max_length=50, default='white')
isFile = models.BooleanField(default=False)
link = models.TextField(default='')
file = models.FileField(upload_to='uploads/', null=True)
tags = models.ManyToManyField('Tag')
class Meta:
ordering = ('title',)
这是我的序列化器:
class TagSerializers(serializers.HyperlinkedModelSerializer):
class Meta:
model = Tag
fields = ('name',)
class SourceSerializers(serializers.ModelSerializer):
tags = TagSerializers(many=True)
class Meta:
model = Source
fields = ('title', 'author', 'language', 'color', 'isFile', 'link', 'file', 'tags')
def create(self, validated_data):
tags_data = validated_data.pop('tags')
source = Source.objects.create(**validated_data)
for tag in tags_data:
t = Tag.objects.create()
t.name = tag.get("name")
t.save()
source.tags.add(t)
source.save()
return source
但是当我尝试通过http请求创建Source对象时 - 创建了对象,但没有对Tags进行任何引用。经过一番研究,我发现create(self,validated_data)中的validated_data不包含“tags”字段,我也发现TagSerializer的验证功能在任何时候都没有被调用。我做错了什么?
使用get_or_create
方法创建Tag对象。
def create(self, validated_data):
tags_data = validated_data.pop('tags')
source = Source.objects.create(**validated_data)
for tag in tags_data:
name = tag.get("name")
t = Tag.objects.get_or_create(name=name)
t.save()
source.tags.add(t)
source.save()
return source
似乎问题出在我的请求中,没有多对多的关系,我们可以使用表单数据,一切都很好,但是当我们添加mant-to-many关系时,我们不再使用表单数据而只能使用应用程序\ JSON
我认为你请求payload
有一些问题。无论如何试试这个
{
"title": "Temp_title",
"author": "author_name",
"language": "english",
"color": "dark",
"isFile": false,
"link": "link_if_needed",
"file": null,
"tags": [
{
"name": "new_tag"
},
{
"name": "tag_1"
},
{
"name": "tag_2"
},
{
"name": "tag_2"
}
]
}
使用requests
模块测试这个
import requests
url = http://host_addrs/api_end_point/
payload = {
"title": "Temp_title",
"author": "author_name",
"language": "english",
"color": "dark",
"isFile": False,
"link": "link_if_needed",
"file": None,
"tags": [
{
"name": "new_tag"
},
{
"name": "tag_1"
},
{
"name": "tag_2"
},
{
"name": "tag_2"
}
]
}
response = requests.post(url=url,data=payload)
让我知道这个是否奏效 :)