在Django中将模型对象从模型复制到另一个模型
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Django中将模型对象从模型复制到另一个模型相关的知识,希望对你有一定的参考价值。
我必须建模。我想将模型对象从模型复制到另一个:Model2是Model1的副本(此模型有太多m2m字段)Model1:
class Profile(models.Model):
user = models.OneToOneField(User)
car = models.ManyToManyField(Car)
job = models.ManyToManyField(Job)
.
.
这是一个调查应用程序。我想在他/她参加调查时保存用户的个人资料(因为他可以在调查后编辑个人资料)我创建了另一个模型以在他进行调查时保存用户资料(我不确定它是正确的方式)
class SurveyProfile(models.Model):
user = models.OneToOneField(SurveyUser) #this is another model that takes survey users
car = models.ManyToManyField(Car)
job = models.ManyToManyField(Job)
如何将用户配置文件从Profile复制到SurveyProfile。
提前致谢
deepcopy
等不起作用,因为类/模型不同。
如果您确定SurveyProfile
具有Profile
*中存在的所有字段,那么这应该有效(未经过测试):
for field in instance_of_model_a._meta.fields:
if field.primary_key == True:
continue # don't want to clone the PK
setattr(instance_of_model_b, field.name, getattr(instance_of_model_a, field.name))
instance_of_model_b.save()
*
(在这种情况下,我建议你制作一个抽象的ProfileBase
类并继承它作为Profile
和SurveyProfile
的具体类,但这不影响我上面提到的)
我很难理解你上面写的内容,因此我不能100%肯定这是否有效,但我认为我会做的就是这样,如果我理解你的话:
class Model2Form(ModelForm):
class Meta:
model = models.Model2
然后
f = Model2Form(**m1.__dict__)
if f.is_valid():
f.save()
但我认为这看起来更像是糟糕的数据库设计,而不是看到整个模型1我无法确定。但是,无论如何,我不知道你为什么要这样做,当你可以简单地在模型级别使用继承,或其他东西来获得相同的行为。
这是我一直在使用的功能,它建立在model_to_dict之上。 Model_to_dict只返回外键的ID而不是它们的实例,所以对于那些我用模型本身替换它们。
def update_model(src, dest):
"""
Update one model with the content of another.
When it comes to Foreign Keys, they need to be
encoded using models and not the IDs as
returned from model_to_dict.
:param src: Source model instance.
:param dest: Destination model instance.
"""
src_dict = model_to_dict(src, exclude="id")
for k, v in src_dict.iteritems():
if isinstance(v, long):
m = getattr(src, k, None)
if isinstance(m, models.Model):
setattr(dest, k, m)
continue
setattr(dest, k, v)
我就是这样做的(注意:这是在Python3中,你可能需要改变一些东西 - 摆脱字典理解 - 如果你使用的是python 2):
def copy_instance_kwargs(src, exclude_pk=True, excludes=[]):
"""
Generate a copy of a model using model_to_dict, then make sure
that all the FK references are actually proper FK instances.
Basically, we return a set of kwargs that may be used to create
a new instance of the same model - or copy from one model
to another.
The resulting dictionary may be used to create a new instance, like so:
src_dict = copy_instance_kwargs(my_instance)
ModelClass(**src_dict).save()
:param src: Instance to copy
:param exclude_pk: Exclude the PK of the model, to ensure new records are copies.
:param excludes: A list of fields to exclude (must be a mutable iterable) from the copy. (date_modified, for example)
"""
# Exclude the PK of the model, since we probably want to make a copy.
if exclude_pk:
excludes.append(src._meta.pk.attname)
src_dict = model_to_dict(src, exclude=excludes)
fks={k: getattr(src, k) for k in src_dict.keys() if
isinstance(getattr(src, k, None), models.Model) }
src_dict.update(fks)
return src_dict
所以,如果我正确地解释你的问题,你有一个旧模型(Profile
),并且你正试图用新模型SurveyProfile
替换它。鉴于这种情况,您可能需要考虑长期使用South等数据库迁移工具。现在,您可以在Django shell(manage.py shell
)中运行脚本:
from yourappname.models import *
for profile in Profile.objects.all():
survey_profile = SurveyProfile()
# Assuming SurveyUser has user = ForeignKey(User)...
survey_profile.user = SurveyUser.objects.get(user=profile.user)
survey_profile.car = profile.car
survey_profile.job = profile.job
survey_profile.save()
使用南方
如果这个项目需要长期维护和更新,我强烈建议使用像South这样的数据库迁移包,它可以让你修改模型上的字段,并轻松地迁移你的数据库。
例如,您建议您的原始模型存在太多ManyToManyField
s。有了南方,你:
- 从模型中删除字段。
- 自动生成架构迁移。
- 应用迁移。
这使您可以重用所有旧代码,而无需更改模型名称或使用数据库。
以上是关于在Django中将模型对象从模型复制到另一个模型的主要内容,如果未能解决你的问题,请参考以下文章
在 knockout.js 中将 observable 从一个视图模型传递到另一个视图模型
如何在 Django 中使用 South 将数据从一个模型迁移到另一个模型?
在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型