Как я могу создать глубокий клон объекта БД в Django? - PullRequest
10 голосов
/ 19 января 2012

Я пытаюсь создать полную копию экземпляра опроса, который имеет несколько разделов, и у каждого раздела есть несколько вопросов, и, наконец, у каждого вопроса есть несколько вариантов. Я использую стандарт django 1.3.1, с MySQL. Мне нужно иметь возможность создать полную копию всех этих элементов для другого владельца опроса. То, что я сейчас имею в виду:

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

Однако, похоже, что он проходит через все циклы без каких-либо ошибок и просто создает копию опроса. Я надеялся, что это скопирует опрос, разделы, вопросы, варианты для этого экземпляра опроса. Просто не могу понять, что я делаю здесь неправильно.

Ответы [ 2 ]

13 голосов
/ 19 января 2012

Поиск в Google "django deep copy" возвращает это на первой странице: http://www.nerdydork.com/copy-model-object-in-django.html

Пример кода:

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

Если я правильно понимаю ваш вопрос, вам нужно изменить еще несколько полей перед сохранением.

1 голос
/ 19 января 2012

Я думаю, что это происходит потому, что survey присвоено survey_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

или эквивалент Джанго

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
...