2012-01-18 32 views
6

我正在嘗試創建一個調查實例的完整副本,其中有幾個部分,每個部分都有幾個問題,最後每個問題都有幾個選項。我正在使用標準的Django 1.3.1,使用MySQL。我需要爲不同的調查所有者創建所有這些元素的完整副本。我目前擁有的觀點是:如何在Django中創建一個DB對象的深層克隆?

survey_new = survey 
    survey_new.title = survey.title + ' -- Copy' 
    survey_new.owner = str(new_owner_id) 
    survey_new.created = datetime.now() 
    survey_new.pk = None 
    survey_new.save() 

    for sec in survey.sections.all().order_by('order'): 
     sec_n = sec 
     sec_n.survey_id = survey_new.id 
     sec_n.pk = None 
     sec_n.save() 

     for q in sec.questions.all().order_by('order'): 
      q_n = q 
      q_n.section_id = sec_n.id 
      q_n.pk = None 
      q_n.save() 

      for op in q.options.all().order_by('order'): 
       op_n = op 
       op_n.question_id = q_n.id 
       op_n.pk = None 
       op_n.save() 

然而,這似乎是通過所有的循環沒有任何錯誤運行,並且只創建調查的副本。我希望這會複製調查實例的調查,部分,問題和選項。似乎無法弄清楚我在這裏做錯了什麼。

+1

一些觀察:1.您應該閱讀['select_related()'](https://docs.djangoproject.com/en/1.3/ref/models/querysets/#select-related)並查看它是否看起來有趣。 2.在複製id值時要非常小心,否則可能會無意中覆蓋數據庫中的* original *項目。 – 2012-01-18 21:56:19

+0

爲什麼不使用'Options.objects.create(...)'和'Section.objects.create(...)'等?你爲什麼試圖與PK的混帳? – 2012-01-18 21:57:38

+0

@Peter:感謝指向select_related()的指針。這應該優化我的代碼:) – Priyeshj 2012-01-18 23:12:10

回答

9

谷歌搜索被收集「Django的深層複製「在第一頁上返回:http://www.nerdydork.com/copy-model-object-in-django.html

The co提供的樣品是:

from copy import deepcopy 
old_obj = deepcopy(obj) 
old_obj.id = None 
old_obj.save() 

如果我正確理解您的問題,您需要在保存之前更改一些字段。

+7

沒有雙關意圖,但不應將名稱「old_obj」恰當地稱爲「new_obj」而不是?我看到,因爲我們正在試圖製作一個obj的副本,從而創造一個新的對象?只是好奇。 – tilaprimera 2015-01-05 09:05:17

+1

@tilaprimera功能沒有區別。它的命名方式是因爲'old_obj'除了id之外,在複製時與obj相同。 – Marcin 2015-01-05 10:18:03

+3

只需注意,這不會複製您正在克隆的對象的關係。這可能是也可能不是期望的行爲,但它是爲了我,所以我需要做別的事情。 :) – bwest87 2015-10-17 04:50:48

1

我想這是因爲分配給surveysurvey_new這行代碼

survey_new = survey 

的那麼當survey_new保存

survey_new.title = survey.title + ' -- Copy' 
survey_new.owner = str(new_owner_id) 
survey_new.created = datetime.now() 
survey_new.pk = None 
survey_new.save() 

survey成爲等於survey_new。例如,你可以檢查它,以便

id(survey) 
# 50016784 
id(survey_new) 
# 50016784 

或者Django的等效

survey.id 
# 10 
survey_new.id 
# 10 

找出問題所需的所有對象都分配之前

survey_section = survey.sections.all().order_by('order') 
# ... all other questions and options 

survey_new = survey 
survey_new.title = survey.title + ' -- Copy' 
survey_new.owner = str(new_owner_id) 
# ... your remaining code