2012-05-28 5 views
1

У меня есть эта модель ...изменения имени файла в Джанго

class MyModel(models.Model): 
    ... 
    file = models.FileField(upload_to='files/',null=True, blank=True) 
    ... 

, когда я загрузить файл, пример имени файла docfile.doc. когда я меняю файл или переписываю его и снова загружаю docfile.doc, файл станет docfile_1.doc, а старый docfile.doc по-прежнему существует.

я делаю загрузку и сохранение данных в django-admin

мой вопрос, как я могу удалить старый docfile.doc если я загрузить новый docfile.doc и имя файла еще docfile.doc?

Может ли кто-нибудь помочь мне в моем случае? спасибо заранее

я попробовать это один:

def content_file_name(instance, filename): 
    print instance 
    print filename 
    file = os.path.exists(filename) 
    print file 
    if file: 
     os.remove(filename) 
    return "file/"+str(filename) 

class MyModel(models.Model): 
     ... 
     file = models.FileField(upload_to=content_file_name,null=True, blank=True) 
     ... 

но ничего СЛУЧИЛОСЬ, когда я загрузить docfile.doc снова, она станет docfile_1.doc и старый docfile.doc все еще существуют.

+1

Django делает это, потому что браузеры кэшируют изображения. Сразу после загрузки нового браузера изображений отображается предыдущий (из его кеша). – sergzach

+0

Не делайте этого! Если вы не добавите @never_cache в свою функцию просмотра. –

ответ

1

я получил его ... я использую этот

def content_file_name(instance, filename): 
    print instance 
    print filename 
    file = os.path.exists("media/file/"+str(filename)) 
    print file 
    if file: 
     os.remove("media/file/"+str(filename)) 
    return "file/"+str(filename) 
+4

Я рекомендую вам использовать 'settings.MEDIA_ROOT' или' settings.MEDIA_URL' вместо жесткого кодирования «media/file /» в вашем коде. – marianobianchi

2

Я не знаю точно, как это сделать, но я думаю, что эти ссылки могут помочь вам:

Here вы можете найти два параметры, которые принимает FileField. Тот, который, я думаю, вас больше всего интересует, - FileField.storage. Вы можете передать объект хранения в этот параметр.

Он говорит:

FileField.storage: Необязательно. Объект хранения, который обрабатывает хранение и извлечение ваших файлов.

Затем, если вы читаете this, вы увидите, что вы можете написать свой собственный объект хранения. Here - некоторое объяснение о том, как это сделать. Я думаю, что вы могли бы просто переопределить метод _save, чтобы выполнить то, что вы хотите сделать (например: если файл уже существует, удалите его перед сохранением новой копии.)

Но будьте осторожны! Я не знаю, какой источник файлов вы собираетесь хранить. Возможно, ваше приложение будет получать множество файлов с тем же именем, хотя они все разные. В этом случае вы хотели бы использовать вызываемый как параметр FileField.upload_to, чтобы определить уникальное имя файла для каждого файла, который получает ваш сайт.

Надеюсь, это поможет вам!

+0

http://djangosnippets.org/snippets/2173/ может помочь – luc

0

Следующий код решает вашу проблему. Вы переопределяете метод pre_save, где изображение фактически сохраняется в хранилище. Пожалуйста, переименуйте функции для своего проекта.Используйте вновь созданное поле изображения ImageFieldWithPermantName с вашим upload_to function (content_file_name).

Если код слишком сложный, вы можете его упростить. Я использую код для выполнения более сложных операций для загрузки изображений: я создаю миниатюры на лету в пользовательской функции _save_image. Таким образом, вы можете упростить его.

from PIL import Image 
import StringIO 
from django.db.models import ImageField 
from django.db.models.fields.files import FileField 
from dargent.settings import MEDIA_ROOT 
import os 

class ImageFieldWithPermanentName(ImageField): 
    def pre_save(self, model_instance, add): 
     file = super(FileField, self).pre_save(model_instance, add) 
     if file and not file._committed: 
      if callable(self.upload_to): 
       path = self.upload_to(model_instance, "") 
      else: 
       path = self.upload_to 
      file.name = path # here we set the same name to a file 
      path = os.path.join(MEDIA_ROOT, path) 
      chunks = _get_chunks(file.chunks()) 
      _save_image(chunks, path) 

     return file  

def _get_chunks(chunks): 
    chunks_ = "" 
    for chunk in chunks: 
     chunks_ += chunk 
    return chunks_ 

def _get_image(chunks): 
    chunks_ = "" 
    for chunk in chunks: 
     chunks_ += chunk 

    virt_file = StringIO.StringIO(chunks_) 
    image = Image.open(virt_file) 
    return image 

def _save_image(chunks, out_file_path): 
    image = _get_image(chunks) 
    image.save(out_file_path, "JPEG", quality = 100)