14

我对 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 )
4

1 回答 1

40

只需更新pk_set就足够了。你不需要做任何额外的工作。保存视频实例后,它将具有 pk=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()
于 2014-10-24T15:15:34.833 回答