我们想在ManyToManyField
方法中访问相关的Model.save
数据预保存,但是该数据尚无法通过Django ORM获得,因为它与相关的ManyToManyField
数据有关,并且只有在post-save
个主要记录。
这是关系的一些示例代码,并且在ManyToMany
中访问相关的Model.save
记录
class Friend(models.Model):
name = models.CharField(max_length=50)
class Person(models.Model):
name = models.CharField(max_length=50)
friends = models.ManyToManyField(Friend)
def save(self, *args, **kwargs):
friends = self.friends.all()
# 'friends' is an empty QuerySet at this point
# I'd like to do something with friends here,
# but it gets set after save
super(Friend, self).save(*args, **kwargs)
在
friends
上传递save
的示例用例:friend = Friend.objects.all()[0]
friend2 = Friend.objects.all()[1]
friends = [friend, friend2]
Person.objects.create(friends=friends)
最佳答案
m2m关系是在实例保存后建立并获得其自己的ID,因此无法在覆盖保存方法中访问它,两种存档方式:
一:在django 1.9之后,交易工具提供了侦听数据库通信的新方法,doc为here。演示代码为:
from django.db import transaction
class Person(models.Model):
name = models.CharField(max_length=50)
friends = models.ManyToManyField(Friend)
def save(self, *args, **kwargs):
instance = super(Person, self).save(*args, **kwargs)
transaction.on_commit(self.update_friend)
return instance
def update_friend(self):
for friend in self.friends.all():
print(friend.__str__())
第二种方法是使用信号,这里是演示:
from django.db.models.signals import m2m_changed
@receiver(m2m_changed, sender=Person.friends.through)
def friends_change(sender, action, pk_set, instance=None, **kwargs):
if action in ['post_add', 'post_remove']:
queryset = instance.friends.all()
for friend in queryset:
print(friend.__str__())