我必须建模。我想将模型对象从模型复制到另一个: Model2是Model1的副本(此模型有太多m2m字段) 型号1:
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)
如何将用户个人资料从个人资料复制到SurveyProfile。
提前致谢
答案 0 :(得分:10)
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
的具体类继承,但这不是影响我上面提到的内容)
答案 1 :(得分:3)
我很难理解你上面写的内容,因此我不能100%肯定这是否有效,但我认为我会做的就是这样,如果我理解你的话: / p>
class Model2Form(ModelForm):
class Meta:
model = models.Model2
然后
f = Model2Form(**m1.__dict__)
if f.is_valid():
f.save()
但我认为这看起来更像是糟糕的数据库设计,而不是看到整个模型1我无法确定。但是,无论如何,我不确定你为什么要这样做,当你可以在模型级别使用继承或其他东西来获得相同的行为时。
答案 2 :(得分:2)
这是我一直在使用的功能,它建立在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)
答案 3 :(得分:0)
我就是这样做的(注意:这是在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
答案 4 :(得分:-1)
因此,如果我正确解释您的问题,您有一个旧模型(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这样的数据库迁移包,它可以让您修改模型上的字段,并轻松地迁移您的数据库。 / p>
例如,您建议您的原始模型存在太多ManyToManyField
。南方,你:
这使您可以重用所有旧代码,而无需更改模型名称或使用数据库。