Ok, he intentado casi todo y no puedo hacer que esto funcione.
- Tengo un modelo Django con un ImageField
- Tengo un código que descarga una imagen a través de HTTP (probado y funciona)
- La imagen se guarda directamente en la carpeta 'upload_to' (el upload_to es el que está configurado en ImageField)
- Todo lo que necesito hacer es asociar la ruta del archivo de imagen ya existente con ImageField
He escrito este código sobre 6 formas diferentes.
El problema con el que me encuentro es que todo el código que estoy escribiendo da como resultado el siguiente comportamiento: (1) Django creará un segundo archivo, (2) cambiará el nombre del nuevo archivo y agregará un _ al final del archivo nombre, luego (3) no transfiera ninguno de los datos dejando básicamente un archivo vacío renombrado. Lo que queda en la ruta 'upload_to' son 2 archivos, uno que es la imagen real y otro que es el nombre de la imagen, pero está vacío, y por supuesto, la ruta ImageField está configurada en el archivo vacío que Django intenta crear .
En caso de que eso no esté claro, intentaré ilustrar:
## Image generation code runs....
/Upload
generated_image.jpg 4kb
## Attempt to set the ImageField path...
/Upload
generated_image.jpg 4kb
generated_image_.jpg 0kb
ImageField.Path = /Upload/generated_image_.jpg
¿Cómo puedo hacer esto sin que Django intente volver a almacenar el archivo? Lo que realmente me gustaría es algo en este sentido ...
model.ImageField.path = generated_image_path
... pero por supuesto eso no funciona.
Y sí, he revisado las otras preguntas aquí, como esta , así como el documento de django en File
ACTUALIZACIÓN Después de más pruebas, solo realiza este comportamiento cuando se ejecuta bajo Apache en Windows Server. Mientras se ejecuta bajo el 'servidor de ejecución' en XP, no ejecuta este comportamiento.
Estoy perplejo
Aquí está el código que se ejecuta con éxito en XP ...
f = open(thumb_path, 'r')
model.thumbnail = File(f)
model.save()
fuente
Respuestas:
Tengo un código que extrae una imagen de la web y la almacena en un modelo. Los bits importantes son:
Eso es un poco confuso porque está sacado de mi modelo y un poco fuera de contexto, pero las partes importantes son:
Avíseme si tiene preguntas o necesita aclaraciones.
Editar: en aras de la claridad, aquí está el modelo (menos cualquier declaración de importación requerida):
fuente
import urlparse
.os.path.basename(urlparse.urlparse(self.url).path)
. Gracias por el post, fue útil.prohibited to prevent data loss due to unsaved related object 'stream'.
Súper fácil si el modelo aún no se ha creado:
Primero , copie su archivo de imagen a la ruta de carga (se supone = 'ruta /' en el siguiente fragmento).
Segundo , usa algo como:
probado y funcionando en django 1.4, podría funcionar también para un modelo existente.
fuente
Solo un pequeño comentario. La respuesta de tvon funciona pero, si estás trabajando en Windows, probablemente quieras hacer
open()
el archivo'rb'
. Me gusta esto:o obtendrá su archivo truncado en el primer
0x1A
byte.fuente
Aquí hay un método que funciona bien y le permite convertir el archivo a cierto formato también (para evitar el error "no se puede escribir el modo P como JPEG"):
donde image es django ImageField o your_model_instance.image aquí hay un ejemplo de uso:
Espero que esto ayude
fuente
Ok, si todo lo que necesita hacer es asociar la ruta del archivo de imagen ya existente con ImageField, entonces esta solución puede ser útil:
Bueno, si es serio, el archivo de imagen ya existente no se asociará con ImageField, pero la copia de este archivo se creará en upload_to dir como 'imgfilename.jpg' y se asociará con ImageField.
fuente
with open('/path/to/already/existing/file', 'rb') as f:
obj.save()
Lo que hice fue crear mi propio almacenamiento que simplemente no guardará el archivo en el disco:
Luego, en mis modelos, para mi ImageField, he usado el nuevo almacenamiento personalizado:
fuente
Si desea simplemente "establecer" el nombre de archivo real, sin incurrir en la carga de cargar y volver a guardar el archivo (!!), o recurrir a un charfield (!!!), puede intentar algo como esto: -
Esto iluminará su model_instance.myfile.url y todo el resto de ellos como si realmente hubiera subido el archivo.
Como dice @ t-stone, lo que realmente queremos es poder establecer instance.myfile.path = 'my-filename.jpg', pero Django actualmente no lo admite.
fuente
La solución más simple en mi opinión:
fuente
Muchas de estas respuestas estaban desactualizadas, y pasé muchas horas frustradas (soy bastante nuevo en Django y el desarrollador web en general). Sin embargo, encontré esta excelente esencia de @iambibhas: https://gist.github.com/iambibhas/5051911
fuente
Es posible que esta no sea la respuesta que está buscando. pero puede usar charfield para almacenar la ruta del archivo en lugar de ImageFile. De esa manera, puede asociar mediante programación la imagen cargada al campo sin volver a crear el archivo.
fuente
Puedes probar:
fuente
fuente
fuente
¡Trabajando! Puede guardar la imagen utilizando FileSystemStorage. mira el siguiente ejemplo
fuente
Puede usar el marco REST de Django y la biblioteca de solicitudes de Python para guardar la imagen mediante programación en Django ImageField
Aquí hay un ejemplo:
fuente
Con Django 3, con un modelo como este:
Si la imagen ya se ha subido, podemos hacer directamente:
o
fuente