如何复制 Django 模型实例,同时保留对原始模型的引用?

How do I duplicate a django model instance, keeping a reference to the original?

The docs举个复制模型实例的例子:

blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1

blog.pk = None
blog.save() # blog.pk == 2

在一个稍微复杂的场景中,我有一个 Article,它可以指向一个 Revision,它保留对其父项的引用(保留所做编辑的历史记录)。 我想复制现有的 Revision,将副本的 parent 设置为原始文件。

class Article:
    revision = models.OneToOneField('Revision')

class Revision:
    article = models.ForeignKey('Article')
    parent = models.ForeignKey('Revision', related_name='children')
    content = models.TextField()

article = get_some_article()
revision = article.revision # ideally I want this to dupe the python object
revision.pk = None # but this create a copy instead
revision.content += " edited"
revision.parent = article.revision # this is the apparent problem
revision.save()

我认为 revision.parent = article.revision 有两个问题。一是自引用,二是还没有保存,无法引用。

我也许可以做这样的事情,除非实例被缓存 (?):

parent = Revision.objects.get(pk=article.revision.pk) #get a duplicate
...
revision.parent = parent

但这很糟糕,因为它涉及整个额外的查询,只是为了复制对象。我应该怎么做?

article = get_some_article()
revision = article.revision
revision.parent = revision # Set the parent to itself
revision.content += " edited"
revision.pk = None
revision.save()  # New revision with parent set to original
# Assuming you are keeping the latest revision reference in article you need to update that also.
article.revision = revision
article.save()