2012-09-10 117 views
5

Sé que aquí hay un hilo similar, pero no encuentro la solución a mi problema.Renombrar archivos en Django FileField

tengo que cambiar el nombre de un archivo que se ahorran de Django models.FileField

yo probamos este

os.rename(old_path, new_path) 
mod.direct_file = File(open(new_path)) 
mod.save() 

Y esta

mod.direct_file.save(new_path, File(open(old_path))) 
os.remove(old_path) 

Y muchas otras maneras, pero nada parecía ayuda. Se crea un nuevo archivo de todas las maneras, sin embargo, los datos en el campo de archivos no cambian en absoluto.

EDIT: SOLUCIONADO

os.rename(old_path, new_path) 
cursor = connection.cursor() 
cursor.execute("UPDATE mods_mod SET direct_file = %s WHERE id = %s", [new_name, mod.id]) 
transaction.commit_unless_managed() 

Respuesta

3

Los actuales estados de documentación de Django:

"Cuando acceda a un FileField en un modelo, se le da una instancia de FieldFile como un proxy para acceder el archivo subyacente ". Vea docs para leer más.

En lugar de utilizar el objeto Archivo de Python para abrir el archivo, debe usar FieldFile.open() para abrir el archivo y luego manipular la ruta del archivo en consecuencia. Después, guarde el objeto modelo, y los cambios en la ruta deberían persistir.

+0

método Open abre ya asignado archivo. FieldFile no tiene un método para abrir otro archivo. – aemdy

+0

El archivo se asigna a través del campo Archivo, ¿correcto? ¿Estás tratando de cambiar todos los archivos de tu modelo o una sola instancia del modelo? – droxey

+0

Me gustaría cambiar el nombre del archivo 'direct_file = models.FileField (default = None, blank = True, null = True, upload_to =" mod_files ") subido en este campo. – aemdy

6

No creo que necesite usar SQL sin formato para esto. Creo que debe cambiar el nombre del archivo mediante el recurso os, luego configure el nombre FileField del modelo con el nuevo nombre. Tal vez algo como:

os.rename(model.direct_file.path, new_path) 
model.direct_file.name = new_name 
model.save() 
1
new_name = 'photos_preview/' + str(uuid.uuid1()) 
os.rename(photo.image_preview.path, settings.MEDIA_ROOT + new_name) 
photo.image_preview.name = new_name 
photo.save() 
1

me encontré con este problema cuando tenía manchas guardados en Django sin extensión de archivo, y quería que corregir. Se usa mejor cuando se repite un queryset filtrado.

No puede cambiar instance.picture.path, e intentar acceder a instance.picture.file. * Dará un error porque al intentarlo se intentará abrir el archivo anterior. El establecimiento de instance.picture.name aún no le permitirá acceder a instance.picture.file. *, Incluso después de guardar.

puede simplemente establecer el propio objeto ImageField a la ubicación y todo saldrá bien:

(probado con Django 1,10)

import imghdr 
import os 

from django.db import models 

class MyModel(models.Model): 
    picture = models.ImageField() 

instance = MyModel.objects.first() 
if os.path.exists(instance.picture.path): 
    extension = imghdr.what(instance.picture.path) 
    os.rename(instance.picture.path, instance.picture.path + '.' + extension) 
    instance.picture = instance.picture.name + '.' + extension 
    instance.save() 
Cuestiones relacionadas