如何解决如何使用信号更新 Django 中的多对多字段
我有两个模型:
class Website(models.Model):
url = models.URLField()
users = models.ManyToManyField(User)
def __str__(self):
return str(self.url)
class Profile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
bio = models.TextField(null=True,blank=True)
def __str__(self):
return str(self.user.username)
这是我试图完成的信号:
@receiver(m2m_changed,sender=Website.users.through)
def update_bio_when_websites_updated(sender,instance,action,reverse,**kwargs):
pass
当网站修改或更新时,我需要创建一个信号来更新用户的生物。
但我不知道。 怎么可能?
解决方法
以下可能是解决方案,但不是使用信号,而是覆盖中的保存方法 网站模型。
class Website(models.Model):
url = models.URLField()
users = models.ManyToManyField(User)
def __str__(self):
return str(self.url)
def save(self,*args,**kwargs):
if not self.pk: # work only for updates
for user in self.users.all():# it may slow down if no of users is high.
user.bio = 'some thing'
user.save()
super().save(*args,**kwargs) # calling the save
注意:如果某个网站的用户数量过多, 迭代连接到网站的所有用户会减慢 应用程序,然后更新用户的生物可以作为后台 任务。
,你可以这样做。
from django.db.models.signals import post_save,m2m_changed
from django.dispatch import receiver
from django.contrib.auth.models import User
from .models import Profile,Website
@receiver(post_save,sender=User)
def save_profile(sender,instance,created,**kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(m2m_changed,sender=Website.users.through)
def update_bio_when_websites_updated(sender,action,reverse,**kwargs):
if action == 'post_add':
if reverse:
instance.profile.bio = '\n'.join(list(map(lambda x: x.url,instance.website_set.all().order_by('url'))))
instance.profile.save()
else:
for user in instance.users.all():
user.profile.bio = '\n'.join(list(map(lambda x: x.url,user.website_set.all().order_by('url'))))
user.profile.save()
此外,还有另一种方法可以试一试。您可以将 update_bio_when_websites_updated
的输入打印到正文中,然后看看需要采取什么操作。
def update_bio_when_websites_updated(sender,pk_set,**kwargs):
if action == 'post_add':
# Add user to website - instance: website
if not reverse:
print(instance)
print(pk_set)
# Add website to user - instance: user
else:
print(instance)
print(pk_set)
通过运行此程序,您将知道该怎么做。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。