【发布时间】:2018-07-05 02:57:08
【问题描述】:
更新:
对于任何好奇的人,我想出了什么、为什么以及如何解决它。
在我看来,我有:
fields = ['html', 'tags', 'title', 'text', 'taken_date', 'image']
我在我的模板中使用 {{ form.as_p }}。显然,一旦从表单中发布,它真的,真的不希望有任何其他内容触及表单中尚未出现的表单字段。
所以我从我的视图中取出了“标签”字段,它起作用了。
感谢所有回复的人。
原始问题:
使用 Django 2.0.1 和 PostgreSQL 9.2.18
我正在编写一个简单的相册应用程序。在其中我有一个照片对象和 PhotoTag 对象。照片可以有很多标签,标签可以关联很多照片,所以它需要是ManyToManyField。
保存提交的照片后,post_save 接收器调用函数来制作缩略图(工作正常)和更新标签的函数。
照片保存正常,update_tags 调用正常,标签从照片中读取正常,标签保存到 PhotoTag 中。但是将两者捆绑在一起的多对多表不会插入新行。除非代码在 update_tags 函数或 post_save 接收函数期间异常退出,否则将调用 update_tags 之后的 thumbs。
我什至尝试使用 connection.cursor 直接写入 m2m 表,它具有相同的行为。
如果我再次尝试在 Photo 对象上调用 save(),我会因为 post_save 信号而陷入无限循环。
我对发生的事情感到困惑。有什么线索吗?
# models.py
def update_tags(instance):
tags = get_tags(instance.image)
# Set initial values
pt = []
tagid = ''
photoid = instance.id
# Loop through tag list and insert into PhotoTag and m2m relation
for x in range(0, len(tags)):
# Make sure this tag doesn't already exist
if PhotoTag.objects.filter(tag_text=tags[x]).count() == 0:
pt = PhotoTag.objects.create(tag_text=tags[x])
tagid = PhotoTag.objects.latest('id').id
instance.tags.add(pt)
else:
# Only working with new tags right now
pass
return
class Photo(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
title = models.CharField(max_length=200, null=True, blank=True)
text = models.TextField(null=True, blank=True)
html = models.BooleanField(default=False)
filename = models.CharField(default='', max_length=100, blank=True,
null=True)
image = models.ImageField(upload_to=upload_path)
location = models.CharField(max_length=100, blank=True, null=True)
entry_date = models.DateTimeField(default=timezone.now)
taken_date = models.DateTimeField(blank=True, null=True)
tags = models.ManyToManyField(PhotoTag, blank=True)
@receiver(post_save, sender=Photo)
def thumbs(sender, instance, **kwargs):
"""
Upon photo save, create thumbnails and then
update PhotoTag and m2m with any Exif/XMP tags
in the photo.
"""
mk_thumb(instance.image, 'mid')
mk_thumb(instance.image, 'th')
mk_thumb(instance.image, 'sm')
update_tags(instance)
return
-------------
From views.py
-------------
class PhotoCreate(LoginRequiredMixin, CreateView):
model = Photo
template_name = 'photogallery/photo_edit.html'
fields = ['html', 'tags', 'title', 'text', 'taken_date', 'image']
def get_initial(self):
self.initial = {'entry_date': timezone.now()}
return self.initial
def form_valid(self, form):
form.instance.author = self.request.user
return super(PhotoCreate, self).form_valid(form)
更新:
def save(self, mkthumb='', *args, **kwargs):
super(Photo, self).save(*args, **kwargs)
if mkthumb != "thumbs":
self.mk_thumb(self.image, 'mid')
self.mk_thumb(self.image, 'th')
self.mk_thumb(self.image, 'sm')
self.update_tags()
mkthumb = "thumbs"
return
【问题讨论】:
-
可能跑题了,但有什么理由使用信号而不是覆盖
save()模型方法?这对我来说更容易和更清晰,并且可能有助于调试此类问题。 -
我曾考虑过,但我不确定我能否正确排序,因为制作缩略图和阅读标签都需要在照片保存到数据库后进行磁盘。也许我会看看通过覆盖模型的 save() 方法可以做什么。
-
当覆盖
save方法时,您可以选择您的操作是在save之前还是之后发生,只需在super()之前或之后编写代码即可。之后阅读和调试会容易得多。我敢肯定,在那之后你会自己发现问题。 -
不,同样的行为。正在建立关系,在 update_tags() 的末尾,我可以根据实现输入
print(instance.tags.all())或print(self.tags.all()),它会输出正确的标签。 -
你能用
save版本的代码编辑你的帖子吗?
标签: python django postgresql manytomanyfield