在多对多标记系统中;如何将照片保存到已存在的标签名称中,并保存照片,并通过表单添加其余标签。
class Photo(models.Model):
title = models.TextField(blank=False, null=True)
path = models.FileField(blank=False, null=True, upload_to='photos/')
class Tag(models.Model):
name = models.TextField(blank=False, null=True)
photos = models.ManyToManyField(Photo)
以下是视图中的示例,该示例将引发Tag.name unique = true的错误。 当然,存在带标签栏的照片foo。
photo = Photo(title='foo2')
photo.save()
bar = form.data['tag'] ** this is tag bar
bar = Tag(name=bar)
bar.save() **will raise error, name bar already exists so you cannot save it
bar.photos.add(instance)
答案 0 :(得分:1)
我为恢复这个老问题并为相反道歉,但我认为提供完整的代码片段对我有所帮助。我已经提到了get_or_create
几次,但要么你误解了我,要么反之亦然。这段代码应该和你写的一样,除了它使用Django的get_or_create
而不是重新发明它并需要捕获IntegrityError
:
instance = Photo(title=form.data['title'])
instance.save()
tag, created = Tag.objects.get_or_create(name=form.data['tags'])
tag.photos.add(instance)
return HttpResponse("Succesful Upload with Tags")
希望这会有所帮助。 : - )
答案 1 :(得分:0)
除非我弄错了,标签'bar'将连接到foo和foo2。 Django中的ManyToMany字段的工作方式是创建一个额外的表,其中每个条目都有一个外键来连接它。
因此,在您的示例中,它将创建一个表photo_photo_tag
,其中包含Photo
的外键和Tag
的外键。因此,标记本身仅在tag
表中保存一次,但在photo_photo_tag
中多次使用外键引用。
有关ManyToMany如何工作的更多信息,请参阅以下内容:
https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/
Django - enforcing ManyToManyField unique items
答案 2 :(得分:0)
我最终做的是,将Tag模型的名称设置为唯一。然后在视图中尝试保存。如果名称存在;它仍然会保存与标签名称id
的关系 instance = Photo(title=form.data['title'])
instance.save()
tag = form.data['tags']
tag = Tag(name=tag)
try:
tag.save() **if the tag is unique, it will save it then add relation
tag.photos.add(instance)
except IntegrityError, e: ** if its not unique, grab the ID of that tag
tag_id = Tag.objects.all().filter(name=tag)
singletag = tag_id[0]
singletag.photos.add(instance) ** then add relation
return HttpResponse("Succesful Upload with Tags")