在Django中复制模型实例及其相关对象/用于可复制对象的算法
我已经为模型Books,Chapters
和Pages
。它们全部由编写User:
from django.db import modelsclass Book(models.Model)
author = models.ForeignKey('auth.User')
class Chapter(models.Model)
author = models.ForeignKey('auth.User')
book = models.ForeignKey(Book)
class Page(models.Model)
author = models.ForeignKey('auth.User')
book = models.ForeignKey(Book)
chapter = models.ForeignKey(Chapter)
我想做的就是复制一个现有的Book
并更新User给其他人。皱纹是我也想复制所有相关模型实例的Book-它所有的Chapters
和Pages
以及!
观察时,事情变得非常棘手Page-
不仅Pages
需要author
更新其字段,而且还需要指向新Chapter
对象!
Django是否支持开箱即用的方式?用于复制模型的通用算法是什么样的?
回答:
由于删除了CollectedObjects,因此它在Django 1.3中不再起作用。参见变更集14507
我在Django片段上发布了我的解决方案。它很大程度上取决于django.db.models.query.CollectedObject
用于删除对象的代码:
from django.db.models.query import CollectedObjectsfrom django.db.models.fields.related import ForeignKey
def duplicate(obj, value, field):
"""
Duplicate all related objects of `obj` setting
`field` to `value`. If one of the duplicate
objects has an FK to another duplicate object
update that as well. Return the duplicate copy
of `obj`.
"""
collected_objs = CollectedObjects()
obj._collect_sub_objects(collected_objs)
related_models = collected_objs.keys()
root_obj = None
# Traverse the related models in reverse deletion order.
for model in reversed(related_models):
# Find all FKs on `model` that point to a `related_model`.
fks = []
for f in model._meta.fields:
if isinstance(f, ForeignKey) and f.rel.to in related_models:
fks.append(f)
# Replace each `sub_obj` with a duplicate.
sub_obj = collected_objs[model]
for pk_val, obj in sub_obj.iteritems():
for fk in fks:
fk_value = getattr(obj, "%s_id" % fk.name)
# If this FK has been duplicated then point to the duplicate.
if fk_value in collected_objs[fk.rel.to]:
dupe_obj = collected_objs[fk.rel.to][fk_value]
setattr(obj, fk.name, dupe_obj)
# Duplicate the object and save it.
obj.id = None
setattr(obj, field, value)
obj.save()
if root_obj is None:
root_obj = obj
return root_obj
以上是 在Django中复制模型实例及其相关对象/用于可复制对象的算法 的全部内容, 来源链接: utcz.com/qa/401413.html