使用Django的m2m_changed在pre_add时修改保存内容
我对Django的信号机制不是很熟悉,需要一些帮助。
我该如何在实例保存之前修改pk_set?我需要返回一些东西给信号的调用者吗(比如kwargs
)?还是说我自己来保存instance
?
举个简单的例子:我想确保所有保存的视频都包含类别pk=1
。我该如何使用m2m_changed
来实现这个?
class Video(models.Model):
category = models.ManyToManyField('Category')
def video_category_changed(sender, **kwargs):
action = kwargs.pop('action', None)
pk_set = kwargs.pop('pk_set', None)
instance = kwargs.pop('instance', None)
if action == "pre_add":
if 1 not in pk_set:
pk_set.update( [ 1 ] ) # adding this to the set
# do something else?
# profit?
m2m_changed.connect( video_category_changed, sender=Video.category.through )
1 个回答
50
只需要更新一下 pk_set
就可以了,没必要做其他的工作。一旦视频实例被保存,它就会有一个类别,类别的编号是1。
from django.db import models
from django.db.models.signals import m2m_changed
from django.dispatch import receiver
class Category(models.Model):
pass
class Video(models.Model):
category = models.ManyToManyField('Category')
@receiver(m2m_changed, sender=Video.category.through)
def video_category_changed(sender, **kwargs):
action = kwargs.pop('action', None)
pk_set = kwargs.pop('pk_set', None)
if action == "pre_add":
if 1 not in pk_set:
pk_set.update([1])
在上面的方法中,类别只有在视频实例被保存后才会被保存。如果你想在 m2m_changed
实例中明确地保存它们,也可以这样做。
@receiver(m2m_changed, sender=Video.category.through)
def video_category_changed(sender, **kwargs):
instance = kwargs.pop('instance', None)
pk_set = kwargs.pop('pk_set', None)
action = kwargs.pop('action', None)
if action == "pre_add":
if 1 not in pk_set:
c = Category.objects.get(pk=1)
instance.category.add(c)
instance.save()