更好地复制模型实例及相关模型的方法
我在寻找一种最快、最简单的方法来复制一个模型实例和相关的模型。我在这里和这里找到了几种方法,但我觉得这些方法都是基于旧版的Django。
我用循环实现了这个功能,但有没有更好的方法呢?我尝试过django-forkit插件,但遇到了一个关于模型中有外键字段指向auth.User的问题。
模型:
class Book(Folder):
filename = models.CharField(max_length=255)
created_by = models.ForeignKey(User)
class Chapter(models.Model):
book = models.ForeignKey(Book)
name = models.CharField(max_length=255, db_index=True)
class Page(models.Model):
book = models.ForeignKey(Book)
attribute_value = hstore.DictionaryField(db_index=True)
复制函数:
book = Book.objects.get(pk=node_id, created_by=request.user)
chapters = Chapter.objects.filter(book=book)
pages = Page.objects.filter(book=book)
book.pk = None
book.id = None
book.filename = book.filename + "_copy"
book.save()
for chapter in chapters:
chapter.book= book
chapter.pk = None
chapter.save()
for page in pages:
page.book= book
page.pk = None
page.save()
1 个回答
1
如果你的模型真的那么简单,我建议就保持现在的样子。
如果不是,或者你想做得更复杂一点;那么我个人比较喜欢的一种设计方式是,明确列出在复制操作中会受到影响的字段,然后逐个处理。这种做法可以避免你在模型的API上乱搞,从而可能导致你的代码无法升级。这样一来,你的模型也能清楚地说明在复制时会发生什么,这对于某些你可能不想复制的字段来说非常方便。例如:
class CopyableModel(models.Model):
# these fields are persisted across copies
_copy_concerns = ['title', 'author', 'body']
def create_copy(self):
attrs = {}
for concern in self._copy_concerns:
attrs[concern] = getattr(self, concern)
# does this work? Might have to access the CopyableModel definition in a different way...
# Like self.__class__.objects.create( ...
return CopyableModel.objects.create(**attrs)
你还可以稍微调整一下,以便处理多对多关系和其他关系。再次强调,不确定在你的具体情况下这样做是否值得,但在需要的时候,这是一种很好的可扩展的模式。