Foo.objects.get(pk="foo")
<Foo: test>
В базу данных я хочу добавить еще один объект, который является копией объекта выше.
Предположим, у моей таблицы есть один ряд. Я хочу вставить объект первой строки в другую строку с другим первичным ключом. Как я могу это сделать?
python
django
django-models
user426795
источник
источник
obj.pk
иobj.id
сделать эту работу в Django 1.4Документация Django для запросов к базе данных содержит раздел о копировании экземпляров модели . Предполагая, что ваши первичные ключи генерируются автоматически, вы получаете объект, который хотите скопировать, устанавливаете первичный ключ
None
и снова сохраняете объект:В этом фрагменте первый
save()
создает исходный объект, а второйsave()
создает копию.Если вы продолжаете читать документацию, есть также примеры того, как обрабатывать два более сложных случая: (1) копирование объекта, который является экземпляром подкласса модели, и (2) также копирование связанных объектов, включая объекты во многих объектах. много отношений.
Примечание к ответу miah: Установка pk
None
упоминается в ответе miah, хотя он не представлен спереди и по центру. Поэтому мой ответ в основном служит для того, чтобы подчеркнуть этот метод как рекомендованный Django способ сделать это.Историческая справка: Это не было объяснено в документации Django до версии 1.4. Впрочем, это было возможно еще до версии 1.4.
Возможная будущая функциональность: в этом билете было сделано вышеупомянутое изменение документации . В ветке комментариев в билете также обсуждалось добавление встроенной
copy
функции для классов моделей, но, насколько я знаю, они решили пока не решать эту проблему. Так что этот «ручной» способ копирования, вероятно, придется сделать пока.источник
Будьте осторожны здесь. Это может быть очень дорого, если вы находитесь в каком-то цикле и извлекаете объекты один за другим. Если вы не хотите звонить в базу данных, просто выполните:
Он делает то же самое, что и некоторые другие ответы, но не вызывает базу данных для извлечения объекта. Это также полезно, если вы хотите сделать копию объекта, который еще не существует в базе данных.
источник
Используйте следующий код:
источник
model_to_dict
принимаетexclude
параметр, что означает, что вам не нужно отдельноеpop
:model_to_dict(instance, exclude=['id'])
Там клон фрагмент здесь , который вы можете добавить к вашей модели , которая делает это:
источник
if
теперь она должна бытьif fld.name != old._meta.pk.name
, т. Е.name
Свойство_meta.pk
экземпляра.Как это сделать было добавлено в официальные документы Django в Django1.4
https://docs.djangoproject.com/en/1.10/topics/db/queries/#copying-model-instances
Официальный ответ аналогичен ответу miah, но в документах указываются некоторые трудности с наследованием и связанными объектами, поэтому вам, вероятно, следует обязательно прочитать документы.
источник
stable
вместо номера версии в URL-адресе, например: docs.djangoproject.com/en/stable/topics/db/queries/…Я столкнулся с парой ошибок с принятым ответом. Вот мое решение.
Примечание: при этом используются решения, которые официально не разрешены в документах Django, и они могут перестать работать в будущих версиях. Я проверил это в 1.9.13.
Первое улучшение заключается в том, что он позволяет вам продолжать использовать оригинальный экземпляр, используя
copy.copy
. Даже если вы не собираетесь повторно использовать экземпляр, этот шаг может быть более безопасным, если клонируемый экземпляр был передан в качестве аргумента функции. Если нет, вызывающая сторона неожиданно получит другой экземпляр, когда функция вернется.copy.copy
кажется, производит мелкую копию экземпляра модели Django желаемым способом. Это одна из вещей, которые я не нашел документированных, но она работает путем травления и расслоения, так что, вероятно, это хорошо поддерживается.Во-вторых, утвержденный ответ оставит все предварительно выбранные результаты прикрепленными к новому экземпляру. Эти результаты не должны быть связаны с новым экземпляром, если вы явно не скопируете отношения ко многим. Если вы пересекаете предварительно выбранные отношения, вы получите результаты, которые не соответствуют базе данных. Нарушение рабочего кода при добавлении предварительной выборки может быть неприятным сюрпризом.
Удаление
_prefetched_objects_cache
- это быстрый и грязный способ удалить все предварительные выборки. Последующие обращения к множеству обращений работают так, как будто предварительной выборки никогда не было. Использование недокументированного свойства, которое начинается с подчеркивания, вероятно, вызывает проблему совместимости, но пока работает.источник
_[model_name]_cache
, которое после удаления я смог назначить новый идентификатор для этой связанной модели, а затем вызватьsave()
. Могут быть побочные эффекты, которые я еще не определил.установка pk на None лучше, sinse Django может правильно создать pk для вас
источник
Это еще один способ клонирования экземпляра модели:
источник
Для клонирования модели с несколькими уровнями наследования, т.е.> = 2 или ModelC ниже
Пожалуйста, обратитесь к вопросу здесь .
источник
Попробуй это
источник