use*_*795 242 python django django-models
Foo.objects.get(pk="foo")
<Foo: test>
Run Code Online (Sandbox Code Playgroud)
在数据库中,我想添加另一个对象,它是上面对象的副本.
假设我的表有一行.我想将第一行对象插入到具有不同主键的另一行中.我怎样才能做到这一点?
mia*_*iah 406
只需更改对象的主键并运行save()即可.
obj = Foo.objects.get(pk=<some_existing_pk>)
obj.pk = None
obj.save()
Run Code Online (Sandbox Code Playgroud)
如果需要自动生成密钥,请将新密钥设置为"无".
更多关于UPDATE/INSERT的信息.
S. *_*rby 130
用于数据库查询的Django文档包括有关复制模型实例的部分.假设您的主键是自动生成的,您将获得要复制的对象,将主键设置为None
,然后再次保存对象:
blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1
blog.pk = None
blog.save() # blog.pk == 2
Run Code Online (Sandbox Code Playgroud)
在此代码段中,第一个save()
创建原始对象,第二个save()
创建副本.
如果你继续阅读文档,还有一些例子来说明如何处理两个更复杂的情况:(1)复制一个对象,它是一个模型子类的实例,(2)还复制相关的对象,包括多个对象 - 很多关系.
关于miah答案的注意事项:在miah的答案None
中提到了设置pk ,虽然它没有显示在前面和中间.所以我的回答主要是强调该方法是Django推荐的方法.
历史记录:在版本1.4之前,Django文档中没有解释这一点.但是,自1.4之前就有可能.
可能的未来功能:上述文档更改在此票证中进行.在故障单的评论帖子中,还有一些关于copy
为模型类添加内置函数的讨论,但据我所知他们决定不解决这个问题.因此,这种"手动"复制方式可能现在必须要做.
Tro*_*eld 42
这里要小心.如果您处于某种循环中并且逐个检索对象,这可能会非常昂贵.如果您不想调用数据库,只需执行以下操作:
from copy import deepcopy
new_instance = deepcopy(object_you_want_copied)
new_instance.id = None
new_instance.save()
Run Code Online (Sandbox Code Playgroud)
它与其他一些答案的作用相同,但它不会使数据库调用来检索对象.如果要复制数据库中尚不存在的对象,这也很有用.
t_i*_*_io 26
使用以下代码:
from django.forms import model_to_dict
instance = Some.objects.get(slug='something')
kwargs = model_to_dict(instance, exclude=['id'])
new_instance = Some.objects.create(**kwargs)
Run Code Online (Sandbox Code Playgroud)
Dom*_*ger 20
有一个克隆片段在这里,你可以添加到您的模型,做到这一点:
def clone(self):
new_kwargs = dict([(fld.name, getattr(old, fld.name)) for fld in old._meta.fields if fld.name != old._meta.pk]);
return self.__class__.objects.create(**new_kwargs)
Run Code Online (Sandbox Code Playgroud)
Mic*_*tra 20
如何做到这一点被添加到Django1.4中的官方Django文档中
https://docs.djangoproject.com/en/1.10/topics/db/queries/#copying-model-instances
官方答案类似于miah的答案,但是文档指出了继承和相关对象的一些困难,所以你应该确保你阅读文档.
我遇到了一些公认的答案。这是我的解决方案。
import copy
def clone(instance):
cloned = copy.copy(instance) # don't alter original instance
cloned.pk = None
try:
delattr(cloned, '_prefetched_objects_cache')
except AttributeError:
pass
return cloned
Run Code Online (Sandbox Code Playgroud)
注意:这使用的解决方案未在Django文档中得到正式批准,因此在以后的版本中可能会停止使用。我在1.9.13中进行了测试。
第一个改进是,它允许您通过使用继续使用原始实例copy.copy
。即使您不打算重用该实例,如果要克隆的实例作为参数传递给函数,执行此步骤也可能更安全。否则,函数返回时,调用方将意外地拥有其他实例。
copy.copy
似乎以所需的方式生成了Django模型实例的浅表副本。这是我未发现的东西之一,但是它可以通过酸洗和酸洗来工作,因此可能得到了很好的支持。
其次,批准的答案将把任何预取结果附加到新实例上。除非您显式复制多对多关系,否则这些结果不应与新实例相关联。如果遍历预取的关系,将得到与数据库不匹配的结果。添加预取时破坏工作代码可能会令人讨厌。
删除_prefetched_objects_cache
是一种剥离所有预取的快捷方法。随后的许多访问就像从未进行过预取一样工作。使用以下划线开头的未记录的属性可能会引起兼容性问题,但现在可以使用。
将pk设置为None更好,Sinse Django可以为您正确创建一个pk
object_copy = MyObject.objects.get(pk=...)
object_copy.pk = None
object_copy.save()
Run Code Online (Sandbox Code Playgroud)
这是克隆模型实例的另一种方法:
d = Foo.objects.filter(pk=1).values().first()
d.update({'id': None})
duplicate = Foo.objects.create(**d)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
111609 次 |
最近记录: |