我有两个模型(发布和展示)。两者都有Datetime-auto字段。我的问题是,帖子更新后,我想更新与该帖子相关的所有显示对象。
我在这里已经读到可以覆盖一个模型的保存方法,但是所有示例都是关于使用外键更新模型,然后调用另一个模型的save方法。就我而言,这是另一种方式。我怎样才能做到这一点 ?
class Post(models.Model):
title = models.CharField(max_length=40)
content = models.TextField(max_length=300)
date_posted = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rooms = models.ManyToManyField(Room, related_name='roomposts', through='Display')
def __str__(self):
return self.title
def get_absolute_url(self):
return "/post/{}/".format(self.pk)
class Display(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
isdisplayed = models.BooleanField(default=0)
date_posted = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.isdisplayed)
我想在所有相关显示对象的相关帖子更改后更新其date_posted。我不知道覆盖保存方法是否在这里起作用。
答案 0 :(得分:1)
在这种情况下,您应该看看Django的反向外键文档 https://docs.djangoproject.com/en/2.2/topics/db/queries/#following-relationships-backward
在您的情况下,您可以覆盖Post模型上的save方法
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
#either: this excutes many sql statments
for display in self.display_set.all():
display.save()
#or faster: this excute only one sql statements,
#but note that this does not call Display.save
self.display_set.all().update(date_posted=self.date_posted)
可以使用display_set
选项更改名称related_name
在“显示”中,您可以更改它:
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='displays')
然后,您可以使用self.display_set
self.displays
答案 1 :(得分:1)
覆盖保存方法有效,但不是,该死,imo。
您需要的是信号:
@receiver(post_save, sender=Post)
def update_displays_on_post_save(sender, instance, **kwargs):
if kwargs.get('created') is False: # This means you have updated the post
# do smth with instance.display_set
通常它进入signals.py
。
另外,您还需要在AppConfig中添加
def ready(self):
from . import signals # noqa