2012-01-18 21 views
6

Tôi đang cố gắng tạo một bản sao hoàn chỉnh của một bản khảo sát có một số phần và mỗi phần có một số câu hỏi và cuối cùng mỗi câu hỏi có một số tùy chọn. Tôi đang sử dụng tiêu chuẩn django 1.3.1, với MySQL. Tôi cần có thể tạo bản sao hoàn chỉnh của tất cả các yếu tố này, cho một chủ sở hữu khảo sát khác. Những gì tôi hiện có trong chế độ xem là:Làm cách nào để tạo bản sao sâu của đối tượng DB trong Django?

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() 

Tuy nhiên, điều này dường như chạy qua tất cả các vòng mà không có bất kỳ lỗi nào và chỉ tạo bản sao khảo sát. Tôi đã hy vọng rằng điều này sẽ sao chép bản khảo sát, các phần, câu hỏi, các tùy chọn cho trường hợp khảo sát đó. Có vẻ như không thể tìm ra những gì tôi đang làm sai ở đây.

+1

Một vài quan sát: 1. Bạn nên đọc ['select_related()'] (https://docs.djangoproject.com/en/1.3/ref/models/querysets/#select-related) và xem liệu nó có trông có vẻ thú vị. 2. Hãy cẩn thận khi sao chép các giá trị id hoặc bạn có thể vô ý ghi đè mục * ban đầu * trong DB. –

+0

Tại sao bạn không sử dụng 'Options.objects.create (...)' và 'Section.objects.create (...)' vv? Tại sao bạn đang cố gắng để đánh lừa xung quanh với PK? –

+0

@Peter: Cảm ơn con trỏ tới select_related(). Điều đó nên tối ưu hóa mã của tôi một chút :) – Priyeshj

Trả lời

9

Googling "django bản sao sâu "trả lại trang này trên trang đầu tiên: http://www.nerdydork.com/copy-model-object-in-django.html

Đồng de sample given is:

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

Nếu tôi hiểu câu hỏi của bạn đúng, bạn sẽ muốn thay đổi một số trường trước khi lưu.

+7

Không có ý định chơi chữ nhưng không nên đặt tên, "old_obj" được gọi là "new_obj" thay thế một cách thích hợp? Tôi thấy từ đó, chúng tôi đang cố gắng tạo một bản sao của obj và do đó tạo ra một đối tượng mới? Chỉ tò mò thôi. – tilaprimera

+1

@tilaprimera Nó không có sự khác biệt về chức năng. Nó được đặt tên theo cách đó bởi vì 'old_obj' là, ngoài id, giá trị giống với obj tại điểm sao chép. – Marcin

+3

Chỉ cần một lưu ý, điều này sẽ không sao chép các mối quan hệ của đối tượng bạn đang nhân bản. Mà có thể hoặc có thể không phải là hành vi mong muốn, nhưng nó là cho tôi, vì vậy tôi cần phải làm một cái gì đó khác. :) – bwest87

1

Tôi nghĩ rằng điều này xảy ra bởi vì survey giao cho survey_new trên dòng mã này

survey_new = survey 

Một sau đó khi survey_new lưu

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 trở thành bằng survey_new. Ví dụ, bạn có thể kiểm tra nó để

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

hoặc Django tương đương

survey.id 
# 10 
survey_new.id 
# 10 

Để tìm ra các vấn đề tất cả các đối tượng cần phải được thu thập trước khi phân

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 
Các vấn đề liên quan