2012-01-18 17 views
6

Estoy tratando de crear una copia completa de una instancia de encuesta, que tiene varias secciones, y cada sección tiene varias preguntas y, finalmente, cada pregunta tiene varias opciones. Estoy usando el estándar django 1.3.1, con MySQL. Necesito poder crear una copia completa de todos estos elementos para un propietario de encuesta diferente. Lo que tengo actualmente en la vista es:¿Cómo puedo crear un clon profundo de un objeto DB en 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() 

Sin embargo, esto parece correr a través de todos los bucles sin ningún error, y sólo la creación de una copia de la encuesta. Esperaba que esto copiara la encuesta, las secciones, las preguntas y las opciones para esa instancia de encuesta. Simplemente no puedo entender lo que estoy haciendo mal aquí.

+1

Un par de observaciones: 1. Debería leer ['select_related()'] (https://docs.djangoproject.com/en/1.3/ref/models/querysets/#select-related) y ver si parece interesante. 2. Tenga mucho cuidado al copiar los valores de id o puede sobrescribir involuntariamente el elemento * original * en el DB. –

+0

¿Por qué no usa 'Options.objects.create (...)' y 'Section.objects.create (...)' etc.? ¿Por qué estás tratando de jugar con los PK? –

+0

@ Peter: Gracias por el puntero a select_related(). Eso debería optimizar un poco mi código :) – Priyeshj

Respuesta

9

googlear "django copia profunda "devuelve esto en la primera página: http://www.nerdydork.com/copy-model-object-in-django.html

The co de muestra dada es:

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

Si entiendo su pregunta correctamente, querrá cambiar algunos campos más antes de guardar.

+7

Sin juego de palabras, pero ¿no debería el nombre "old_obj" llamarse apropiadamente "new_obj" en su lugar? Veo que, estamos tratando de hacer una copia de obj y hacer un nuevo objeto? Sólo curioso. – tilaprimera

+1

@tilaprimera No hace diferencia a la funcionalidad. Se llama así porque 'old_obj' es, además del id, un valor idéntico a obj en el momento de la copia. – Marcin

+3

Solo una nota, esto no copiará las relaciones del objeto que estás clonando. Que puede o no ser el comportamiento deseado, pero fue para mí, así que tengo que hacer otra cosa. :) – bwest87

1

creo que esto sucede porque survey asignados a survey_new en esta línea de código

survey_new = survey 

Una luego cuando survey_new salvados

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 convirtió igual a survey_new. Por ejemplo, usted puede comprobarlo por lo

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

o Django equivalente

survey.id 
# 10 
survey_new.id 
# 10 

Para averiguar el tema todos los objetos requeridos tienen que ser recogidos antes de la asignació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 
Cuestiones relacionadas