django m2m_随定制型号更改

django m2m_随定制型号更改,django,django-models,django-signals,Django,Django Models,Django Signals,在Django中,我有两个模型“Author”和“Publication”,它们与多对多字段相关联,因此我可以为出版物指定不同的作者。此外,我必须使用一个自定义的贯穿模型“Authorship”来定义正确的顺序 class Author(models.Model): first_name = models.CharField(max_length=48) ..... class Authorship(models.Model): author = models.For

在Django中,我有两个模型“Author”和“Publication”,它们与多对多字段相关联,因此我可以为出版物指定不同的作者。此外,我必须使用一个自定义的贯穿模型“Authorship”来定义正确的顺序

class Author(models.Model):
    first_name = models.CharField(max_length=48)
    .....


class Authorship(models.Model):
    author = models.ForeignKey(Author)
    publication = models.ForeignKey('Publication')
    order_of_authorship = models.IntegerField(default=1)


class Publication(models.Model):
    title = models.CharField(max_length=128)
    authors = models.ManyToManyField(Author, through=Authorship)
    year = models.IntegerField(max_length=4)
    ...

    citation_key = models.CharField(max_length=9, blank=True, default="")
目前,我使用管理界面用“发布”表单和内联表单“Authorship”填充数据

我现在想要实现的目标是: 数据更改后,应自动填充额外的引文关键字字段(如“Einstein1950”)

我想做的是: 我发现使用一定是最好的做法

但是,当我更改作者身份时,“Publication.authors.through”上的“m2m_changed”信号不会被触发

@receiver(m2m_changed, sender=Publication.authors.through)
def authors_changed(sender, **kwargs):
    print("authors changed")
在a中也讨论了这个问题,作者似乎在through模型上使用了“post_save”

@receiver(post_save, sender=Authorship)
def authorship_changed(sender, instance, **kwargs):
    print("authors changed")
这似乎是可行的,但我必须记住,删除尚未涵盖,因此我添加了一个post_delete-signal:

@receiver(post_delete, sender=Authorship)
def authorship_deleted(sender, instance, **kwargs):
    print("authors deleted")
现在的问题是:如果我添加4个作者,我将触发该事件4次。如前所述,如果我想更新我的引文索引键,这种情况也会发生4次

这是正确的解决方案吗?还是有更好的最佳实践?我想它一定是在m2m_改变信号的情况下工作的,但我不知道如何工作。 因为我是Django的新手,我不知道这对你来说是否是显而易见的解决方案。此外,在这种情况下,不必要的计算不应该有很大的影响,但这一点都不好


我只在Django-Trac中找到了一个非常古老的方法,它似乎也解决了这个问题。但是还没有解决方案。

这是一个已知的bug,在Django上报道过。

你找到解决方案了吗?没有,我没有找到更好的解决方案,而且这个解决方案在我看来是可行的(尽管它并不完美)。一位同事建议使用JavaScript在表单中创建键,例如在隐藏字段中。如果您能确保在对特定字段进行更改的每种表单中都使用它,那么这可能是一个更好的解决方案。谢谢您回复我。太糟糕了。我使用了一个时间戳(以避免连续4次更新)-远非完美-类似于您的解决方案,但纯粹是后端。还有一个开放错误“删除引用对象时未发送m2m_更改信号”: