如何使用 django-simple-history 存储 ManyToManyField 的历史记录。

问题描述 投票:0回答:4

如何使用 django-simple-history 存储 ManyToManyField 的历史记录。我使用带有属性 m2m_filds 的 HistoricalRecords 但它抛出错误:意外的关键字参数“m2m_fields”

python django history manytomanyfield django-simple-history
4个回答
6
投票

我是 GitHub 上的 Macro1,我猜是 django-simple-history 事实上的维护者。

从您的问题来看,您似乎只是询问与其他字段相比的一般 ManyToManyField 支持。简而言之,我们目前不支持它。

ManyToManyFields 实际上创建了一个中间模型,表示您正在使用的两个模型之间的关系。

如果您想跟踪该关系,我建议创建一个 'through' 模型 表示该关系并将其传递到 ManyToManyField 构造函数中。然后,您可以通过模型注册它以跟踪其历史记录。如果您在设置时遇到“意外的关键字参数‘m2m_fields’”之类的错误,请在我们的跟踪器中打开问题。


1
投票

尽管 django-simple-history 不允许拥有多对多关系的历史表,但实际上有一种方法可以实现这一点。

您可以做的是手动创建多对多表,而不是使用 djangos 添加和删除,只需创建和删除关系。如果你看一个例子,我们会得到:

class Class(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    history = HistoricalRecords()

class Student(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    classes = models.ManyToManyField(Class)
    history = HistoricalRecords()

您可以使用以下方法手动创建多对多表:

class Class(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    history = HistoricalRecords()

class Student(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    history = HistoricalRecords()

class StudentClasses(models.Model):
    student = models.ForeignKey(Student)
    class = models.ForeignKey(Class)
    history = HistoricalRecords()

如果您现在使用:

StudentClasses.objects.create(student=student, class=class)
而不是
student.classes.add(class)
delete()
而不是
student.classes.remove(class)
,您将在历史表和相同的多对多表中跟踪所有内容。


0
投票

正如 django-simple-history says 的作者所说,这不可能仅检测特定字段的变化,因为

正如您所知,简单的历史并不关注价值观 完全保存了。它会在每次保存时盲目地保存一个新的历史版本 或删除信号。

他还说Field Tracker可能可以完成这项工作。


0
投票

使用 django-simple-history==3.3.0,您现在可以包含多对多字段,如下所示:

class Class(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    history = HistoricalRecords()

class Student(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    classes = models.ManyToManyField(Class)
    history = HistoricalRecords(m2m_fields=[classes])
© www.soinside.com 2019 - 2024. All rights reserved.