Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a deep clone of a DB object in Django?

I am trying to create a complete copy of a survey instance, which has several sections, and each section has several questions and finally each question has several options. I am using standard django 1.3.1, with MySQL. I need to be able to create a complete copy of all these elements, for a different survey owner. What I currently have in the view is:

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

However, this seems to run through all the loops without any errors, and just creating a copy of survey. I was hoping that this would copy the survey, sections, questions, options for that survey instance. Just can't seem to figure out what I am doing wrong here.

like image 853
Priyeshj Avatar asked Jan 18 '12 21:01

Priyeshj


People also ask

How do I copy an object in Django?

There is no built-in method for copying model instances, it is possible to create new instance with all fields values copied. If an instance is saved with instance's pk set to None , the instance is used to create a new record in the DB. That means every field other than the PK is copied.

How do I copy a QuerySet in Django?

all() Returns a copy of the current QuerySet (or QuerySet subclass). This can be useful in situations where you might want to pass in either a model manager or a QuerySet and do further filtering on the result. After calling all() on either object, you'll definitely have a QuerySet to work with.

Which method is used to save a model in DB in Python Django?

Saving objects. To save an object back to the database, call save() : Model.

How do I get unique QuerySet in Django?

Let us say you want to retrieve all unique user_id values from your sales table, then here is the query for it. If you want to get distinct objects, instead of values, then remove flat=True from the above query, and use values() instead of values_list().


2 Answers

Googling "django deep copy" returns this on the first page: Copy Model Object in Django | Nerdy Dork

The code sample given is:

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

If I understand your question correctly, you will want to change some more fields before saving.

like image 176
Marcin Avatar answered Oct 24 '22 01:10

Marcin


I think this happens because survey assigned to survey_new on this line of code

survey_new = survey

An then when survey_new saved

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 became equal to survey_new. For example you can check it so

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

or Django equivalent

survey.id
# 10
survey_new.id
# 10

To figure out the issue all required objects have to be collected before assignment

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
like image 1
Alexey Savanovich Avatar answered Oct 24 '22 03:10

Alexey Savanovich