在Django中将字段从一个实例复制到另一个实例 [英] Copy fields from one instance to another in 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屋!