2012-09-10 16 views
5

So che c'è un thread molto simile qui, ma non riesco a trovare la soluzione al mio problema.Rinominare i file in Django FileField

Ho bisogno di rinominare un file che è salvare nel Django models.FileField

Ho provato questo

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

E questo

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

E molti altri modi, ma niente sembrava Aiuto. Un nuovo file viene creato in tutti i modi, tuttavia, i dati nel file non cambiano affatto.

EDIT: Risolto

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() 

risposta

3

Gli attuali documentazione afferma Django:

"Quando si accede a un FileField su un modello, si è dato un esempio di FieldFile come proxy per l'accesso il file sottostante. " Vedi docs per ulteriori letture.

Invece di utilizzare l'oggetto File Python per aprire il file, è necessario utilizzare FieldFile.open() per aprire il file, quindi modificare il percorso del file di conseguenza. In seguito, salvare l'oggetto del modello e le modifiche al percorso dovrebbero persistere.

+0

metodo Open apre già il file assegnato. FieldFile non ha alcun metodo per aprire un altro file. – aemdy

+0

Il file viene assegnato tramite FileField, corretto? Stai cercando di cambiare tutti i file nel tuo modello o una singola istanza del modello? – droxey

+0

Mi piacerebbe rinominare il file 'direct_file = models.FileField (default = None, blank = True, null = True, upload_to =" mod_files ")' caricato in questo campo. – aemdy

6

Non penso che sia necessario utilizzare SQL raw per questo. Penso che sia necessario rinominare il file utilizzando la funzione os, quindi impostare il nome del modello FileField con il nuovo nome. Forse qualcosa di simile:

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

mi sono imbattuto in questo problema quando ho avuto blobs salvati in Django senza estensione di file, e volevo correggere questo. Si utilizza al meglio quando si esegue il ciclo su un queryset filtrato.

Non è possibile modificare instance.picture.path e tentare di accedere a instance.picture.file. * Verrà visualizzato un errore poiché l'accesso tenterà di aprire il file precedente. L'impostazione di instance.picture.name non ti consentirà comunque di accedere a instance.picture.file. *, Anche dopo il salvataggio.

si può semplicemente impostare l'oggetto ImageField stesso per la posizione e tutto funzionerà:

(testato 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() 
Problemi correlati