Foo.objects.get(pk="foo")
<Foo: test>
En la base de datos, quiero agregar otro objeto que es una copia del objeto anterior.
Supongamos que mi mesa tiene una fila. Quiero insertar el objeto de la primera fila en otra fila con una clave primaria diferente. ¿Cómo puedo hacer eso?
python
django
django-models
usuario426795
fuente
fuente
obj.pk
yobj.id
hacer que esto funcione en Django 1.4La documentación de Django para consultas de bases de datos incluye una sección sobre cómo copiar instancias de modelos . Suponiendo que sus claves primarias se generan automáticamente, obtiene el objeto que desea copiar, establece la clave primaria
None
y guarda el objeto nuevamente:En este fragmento, el primero
save()
crea el objeto original y el segundosave()
crea la copia.Si sigue leyendo la documentación, también hay ejemplos sobre cómo manejar dos casos más complejos: (1) copiar un objeto que es una instancia de una subclase de modelo, y (2) también copiar objetos relacionados, incluidos objetos en muchos -muchas relaciones.
Nota sobre la respuesta de miah: la configuración de pk
None
se menciona en la respuesta de miah, aunque no se presenta al frente y al centro. Entonces mi respuesta sirve principalmente para enfatizar ese método como la forma recomendada de Django para hacerlo.Nota histórica: esto no se explicó en los documentos de Django hasta la versión 1.4. Sin embargo, ha sido posible desde antes de 1.4.
Posible funcionalidad futura: el cambio de documentos antes mencionado se realizó en este ticket . En el hilo de comentarios del ticket, también hubo una discusión sobre la adición de una
copy
función incorporada para las clases de modelo, pero que yo sepa, decidieron no abordar ese problema todavía. Por lo tanto, esta forma de copia "manual" probablemente tendrá que funcionar por ahora.fuente
Ten cuidado aquí. Esto puede ser extremadamente costoso si está en algún tipo de bucle y está recuperando objetos uno por uno. Si no desea la llamada a la base de datos, simplemente haga lo siguiente:
Hace lo mismo que algunas de estas otras respuestas, pero no hace que la base de datos llame para recuperar un objeto. Esto también es útil si desea hacer una copia de un objeto que aún no existe en la base de datos.
fuente
Use el siguiente código:
fuente
model_to_dict
toma unexclude
parámetro, lo que significa que no necesita el separadopop
:model_to_dict(instance, exclude=['id'])
Hay un fragmento de clon de aquí , que se puede añadir a su modelo que hace esto:
fuente
if
ahora debe serif fld.name != old._meta.pk.name
, es decir, laname
propiedad de la_meta.pk
instancia.Cómo hacer esto se agregó a los documentos oficiales de Django en Django1.4
https://docs.djangoproject.com/en/1.10/topics/db/queries/#copying-model-instances
La respuesta oficial es similar a la respuesta de miah, pero los documentos señalan algunas dificultades con la herencia y los objetos relacionados, por lo que probablemente debería asegurarse de leer los documentos.
fuente
stable
lugar del número de versión en la URL, como este: docs.djangoproject.com/en/stable/topics/db/queries/…Me he encontrado con un par de trampas con la respuesta aceptada. Aquí está mi solución.
Nota: esto utiliza soluciones que no están oficialmente autorizadas en los documentos de Django, y pueden dejar de funcionar en futuras versiones. Probé esto en 1.9.13.
La primera mejora es que le permite continuar utilizando la instancia original, utilizando
copy.copy
. Incluso si no tiene la intención de reutilizar la instancia, puede ser más seguro realizar este paso si la instancia que está clonando se pasó como argumento a una función. De lo contrario, la persona que llama inesperadamente tendrá una instancia diferente cuando la función regrese.copy.copy
parece producir una copia superficial de una instancia de modelo Django de la manera deseada. Esta es una de las cosas que no encontré documentada, pero funciona encurtiendo y desenredando, por lo que probablemente tenga un buen soporte.En segundo lugar, la respuesta aprobada dejará los resultados obtenidos previamente adjuntos a la nueva instancia. Esos resultados no deben asociarse con la nueva instancia, a menos que copie explícitamente las relaciones de muchos. Si recorre las relaciones captadas previamente, obtendrá resultados que no coinciden con la base de datos. Romper el código de trabajo cuando agrega una captación previa puede ser una desagradable sorpresa.
Eliminar
_prefetched_objects_cache
es una forma rápida y sucia de eliminar todas las captaciones previas. Los accesos posteriores a muchos funcionan como si nunca hubiera una captación previa. El uso de una propiedad no documentada que comienza con un guión bajo probablemente requiera problemas de compatibilidad, pero funciona por ahora.fuente
_[model_name]_cache
, que, una vez eliminada, pude asignar una nueva ID para ese modelo relacionado, y luego llamarsave()
. Todavía podría haber efectos secundarios que aún no he determinado.establecer pk en None es mejor, sinse Django puede crear correctamente un pk para usted
fuente
Esta es otra forma de clonar la instancia del modelo:
fuente
Para clonar un modelo con múltiples niveles de herencia, es decir,> = 2, o ModelC a continuación
Por favor, consulte la pregunta aquí .
fuente
Prueba esto
fuente