【问题标题】:Better way to duplicate model instance and related model复制模型实例和相关模型的更好方法
【发布时间】:2014-09-26 22:29:23
【问题描述】:

我正在寻找最快、最简单的方法来复制模型实例和相关模型。我发现了一些技术 here 和 here 但我认为它们是基于旧的 django 版本。

我已经通过循环实现了它,但是有没有更好的方法呢?我尝试了django-forkit plugin,但遇到了problem with model that have a foreignkey field with 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()

【问题讨论】:

  • 鉴于您的模型简单,我会坚持使用您的解决方案,但如果您正在寻找更通用的方法,请查看NestedObjects 类:stackoverflow.com/questions/12158714/…
  • @Germano,感谢您的链接。我想知道你是如何在 final 复制所有嵌套对象的。
  • 您好,我觉得这个解决方案没问题;您还可以查看 ORM 的bulk_create 方法,看看是否可以在不多次访问数据库的情况下保存章节和页面。 docs.djangoproject.com/en/dev/ref/models/querysets/#bulk-create。 (也就是说,如果在 Chapter.save() 和 Page.save() 中当然没有发生奇怪的工作人员)

标签: python django


【解决方案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)

您可以稍微调整一下以处理 m2m 和其他关系。同样,不确定在您的特定情况下是否值得麻烦,但是当您需要它时,这是一个很好的可扩展模式。

【讨论】:

    猜你喜欢
    • 2016-05-31
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    相关资源
    最近更新 更多