在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类并继承它作为ProfileSurveyProfile的具体类,但这不影响我上面提到的)

另一答案

我很难理解你上面写的内容,因此我不能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这样的数据库迁移包,它可以让你修改模型上的字段,并轻松地迁移你的数据库。

例如,您建议您的原始模型存在太多ManyToManyFields。有了南方,你:

  1. 从模型中删除字段。
  2. 自动生成架构迁移。
  3. 应用迁移。

这使您可以重用所有旧代码,而无需更改模型名称或使用数据库。

以上是关于在Django中将模型对象从模型复制到另一个模型的主要内容,如果未能解决你的问题,请参考以下文章

在 knockout.js 中将 observable 从一个视图模型传递到另一个视图模型

如何在 Django 中使用 South 将数据从一个模型迁移到另一个模型?

在 django 1.8 中将数据从原始用户模型迁移到自定义用户模型

将Django模型从一个应用程序移动到另一个[重复]

在 RAILS 中将模型从一个控制器动作传递到另一个控制器动作的替代方法

在Django中将计算值从视图保存到模型