Foo.objects.get(pk="foo")
<Foo: test>
No banco de dados, desejo adicionar outro objeto, que é uma cópia do objeto acima.
Suponha que minha tabela tenha uma linha. Quero inserir o primeiro objeto de linha em outra linha com uma chave primária diferente. Como eu posso fazer isso?
python
django
django-models
user426795
fonte
fonte
obj.pk
eobj.id
fazer isso funcionar no Django 1.4A documentação do Django para consultas ao banco de dados inclui uma seção sobre como copiar instâncias de modelo . Supondo que suas chaves primárias sejam geradas automaticamente, você obtém o objeto que deseja copiar, define a chave primária
None
e salva o objeto novamente:Nesse trecho, o primeiro
save()
cria o objeto original e o segundosave()
cria a cópia.Se você continuar lendo a documentação, também haverá exemplos de como lidar com dois casos mais complexos: (1) copiar um objeto que é uma instância de uma subclasse de modelo e (2) copiar objetos relacionados, incluindo objetos de muitos para muitas relações.
Nota sobre a resposta de miah: Definir o pk como
None
é mencionado na resposta de miah, embora não seja apresentado na frente e no centro. Portanto, minha resposta serve principalmente para enfatizar esse método como a maneira recomendada pelo Django de fazer isso.Nota histórica: Isso não foi explicado nos documentos do Django até a versão 1.4. Isso foi possível desde antes da versão 1.4, no entanto.
Possível funcionalidade futura: a alteração dos documentos acima foi feita neste ticket . No tópico de comentários do ticket, houve também uma discussão sobre a adição de uma
copy
função interna para as classes de modelo, mas até onde eu sei, eles decidiram não resolver esse problema ainda. Portanto, essa maneira "manual" de copiar provavelmente terá que ser feita por enquanto.fonte
Tenha cuidado aqui. Isso pode ser extremamente caro se você estiver em um loop de algum tipo e estiver recuperando objetos um por um. Se você não deseja a chamada para o banco de dados, basta:
Ele faz o mesmo que algumas dessas outras respostas, mas não faz a chamada ao banco de dados para recuperar um objeto. Isso também é útil se você deseja fazer uma cópia de um objeto que ainda não existe no banco de dados.
fonte
Use o código abaixo:
fonte
model_to_dict
leva umexclude
parâmetro, que significa que você não precisa do separadopop
:model_to_dict(instance, exclude=['id'])
Há um trecho de clone aqui , que você pode adicionar ao seu modelo que faz isso:
fonte
if
agora precisa serif fld.name != old._meta.pk.name
, ou seja, aname
propriedade da_meta.pk
instância.Como fazer isso foi adicionado aos documentos oficiais do Django no Django1.4
https://docs.djangoproject.com/en/1.10/topics/db/queries/#copying-model-instances
A resposta oficial é semelhante à resposta de miah, mas os documentos apontam algumas dificuldades com herança e objetos relacionados, portanto, você deve ter certeza de ler os documentos.
fonte
stable
vez do número da versão no URL, assim: docs.djangoproject.com/en/stable/topics/db/queries/…Encontrei algumas dicas com a resposta aceita. Aqui está a minha solução.
Nota: isso usa soluções que não são oficialmente sancionadas nos documentos do Django e podem deixar de funcionar em versões futuras. Eu testei isso em 1.9.13.
A primeira melhoria é que ela permite que você continue usando a instância original, usando
copy.copy
. Mesmo que você não pretenda reutilizar a instância, pode ser mais seguro executar esta etapa se a instância que você está clonando foi passada como argumento para uma função. Caso contrário, o chamador inesperadamente terá uma instância diferente quando a função retornar.copy.copy
parece produzir uma cópia superficial de uma instância do modelo Django da maneira desejada. Essa é uma das coisas que não encontrei documentada, mas funciona com decapagem e remoção, portanto provavelmente é bem suportada.Em segundo lugar, a resposta aprovada deixará quaisquer resultados pré-buscados anexados à nova instância. Esses resultados não devem ser associados à nova instância, a menos que você copie explicitamente os relacionamentos entre muitos. Se você percorrer os relacionamentos pré-buscados, obterá resultados que não correspondem ao banco de dados. Quebrar o código de funcionamento quando você adiciona uma pré-busca pode ser uma surpresa desagradável.
A exclusão
_prefetched_objects_cache
é uma maneira rápida e suja de remover todos os prefets. Os acessos subsequentes a muitos funcionam como se nunca houvesse uma pré-busca. O uso de uma propriedade não documentada que começa com um sublinhado provavelmente está solicitando problemas de compatibilidade, mas funciona por enquanto.fonte
_[model_name]_cache
, que, uma vez excluída, pude atribuir um novo ID para esse modelo relacionado e depois ligarsave()
. Ainda pode haver efeitos colaterais que ainda não foram determinados.definir pk como None é melhor, o sinse Django pode criar corretamente um pk para você
fonte
Esta é outra maneira de clonar a instância do modelo:
fonte
Para clonar um modelo com vários níveis de herança, ou seja,> = 2 ou ModelC abaixo
Por favor, consulte a pergunta aqui .
fonte
Tente isto
fonte