在Django中将字段从一个实例复制到另一个实例 [英] Copy fields from one instance to another in Django

查看:168
本文介绍了在Django中将字段从一个实例复制到另一个实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码,它将一个现有的实例和另一个模型中的存档复制,然后将其替换为草稿副本。



当前代码

 code> def archive_calc(self,rev_num,primary_field):
model_a = Calc.objects.get(tag_number__tag_number = primary_field,revision_number = rev_num)#Current修订实例
model_b = CalcArchive()#Draft实例

#Copies数据到归档模型
for model_a._meta.fields中的字段:
setattr(model_b,field.name,getattr(model_a,field.name))

model_b.pk =无
model_b.current_revision = False
model_b.save()

model_a.delete()

这样做不错,但是我需要更改系统以允许某些具有外键的型号,当实例被归档/删除相关记录随之被删除。所以我解决这个问题的想法是将草稿记录的变化复制到以前的记录,然后删除草稿,从而维护外键相关记录。



解决方案的想法

  def archive_calc(self,rev_num,primary_field) b $ b model_a = Calc.objects.get(tag_number__tag_number = primary_field,revision_number = rev_num)#Current修订版本
model_b = CalcArchive()#Archive Instance
model_c = Calc.objects.get(pk = self .object.pk)#Draft实例

#Copies数据到存档模型
for model_a._meta.fields中的字段:
setattr(model_b,field.name,getattr(model_a ,field.name))

model_b.pk =无
model_b.current_revision = False
model_b.save()

#来自草稿的数据实例到当前修订实例
在model_c._meta.fields中的字段:
setattr(model_a,field.name,getattr(mo del_c,field.name))

model_c.delete()

不幸的是上述解决方案不起作用,它似乎忽略了副本,并按照当前代码继续工作。如果我在model_c._meta.fi ... 中的字段之后添加 model_a.save(),系统卡住在循环中并最终抛出最大递归深度超过cmp



任何帮助将像往常一样欣赏,如果我正在调用错误的树,请让我知道。

解决方案

似乎是一个非常漂亮,简单的解决方案。

  def archive_calc(self,rev_num,primary_field):
model_a = Calc.objects.get(calc_details__calc_serial_number = primary_field,revision_number = rev_num)
model_b = CalcArchive()

object_list_annual = model_a.calcreview_set.filter(calc__calc_details = primary_field)
object_list_ageing = model_a.calcitem_set.filter(calc__calc_details = primary_field)

在object_list_annual中的obj:
obj.calc_id = self.object.id
obj.save()
object_list_ageing中的obj:
obj.calc_id = self.object.id
obj.save()

for model_a中的字段。 _meta.fields:
setattr(model_b,field.name,getattr(model_a,field.name))
model_b.pk =无
model_b.current_revision = False
model_b.save ()

model_a.delete()

此移动相关通过将 _id 字段设置为与 self.object.id 相同的对象。



Ive运行了几个测试,这似乎完全正是我正在寻找的最小的代码,没有额外的安装。



希望这有助于某人,请随时指出我的答案中的任何潜在的陷阱。


I have the following code which takes an existing instance and copies, or 'archives' it, in another model and then deletes it replacing it with the draft copy.

Current Code

def archive_calc(self, rev_num, primary_field):
    model_a = Calc.objects.get(tag_number__tag_number = primary_field, revision_number = rev_num) #Current Revision instance
    model_b = CalcArchive() #Draft instance

    #Copies data to archive model
    for field in model_a._meta.fields:
        setattr(model_b, field.name, getattr(model_a, field.name))

    model_b.pk = None
    model_b.current_revision = False
    model_b.save()

    model_a.delete()

This works fine however i need to change the system to allow for certain models with foreign keys as when an instance is archived/deleted the related records are deleted along with it. So my idea to fix this is to have the changes from the draft record copied to the previous record and then have the draft deleted thus maintaining the foreign key related records.

Solution idea

def archive_calc(self, rev_num, primary_field):
    model_a = Calc.objects.get(tag_number__tag_number = primary_field, revision_number = rev_num) #Current Revision instance
    model_b = CalcArchive() #Archive Instance
    model_c = Calc.objects.get(pk = self.object.pk) #Draft instance

    #Copies data to archive model
    for field in model_a._meta.fields:
        setattr(model_b, field.name, getattr(model_a, field.name))

    model_b.pk = None
    model_b.current_revision = False
    model_b.save()

    #Copies data from draft instance to current revision instance
    for field in model_c._meta.fields:
        setattr(model_a, field.name, getattr(model_c, field.name))

    model_c.delete()

Unfortunately the above solution doesn't work, it just seems to ignore the copy and continues to work as per 'Current Code'. If I add model_a.save() after for field in model_c._meta.fi... the system gets stuck in a loop and eventually throws maximum recursion depth exceeded in cmp.

Any help would be much appreciate as usual and if im barking up the wrong tree please let me know.

解决方案

After alot of poking around and reading the Django docs I have come up with what seems to be a pretty nice, simple solution.

def archive_calc(self, rev_num, primary_field):
    model_a = Calc.objects.get(calc_details__calc_serial_number = primary_field, revision_number = rev_num)
    model_b = CalcArchive()

    object_list_annual = model_a.calcreview_set.filter(calc__calc_details = primary_field)
    object_list_ageing = model_a.calcitem_set.filter(calc__calc_details = primary_field)

    for obj in object_list_annual:
        obj.calc_id = self.object.id
        obj.save()
    for obj in object_list_ageing:
        obj.calc_id = self.object.id
        obj.save()

    for field in model_a._meta.fields:
        setattr(model_b, field.name, getattr(model_a, field.name))
    model_b.pk = None
    model_b.current_revision = False
    model_b.save()

    model_a.delete()

This 'moves' the related objects by setting the _id fields to the same as self.object.id.

Ive ran several tests and this seems to achieve exactly what I was looking for with minimal code and no extra installs.

Hope this helps someone and please feel free to point out any potential pitfalls in my answer.

这篇关于在Django中将字段从一个实例复制到另一个实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆