11

Apr

Filed in Code, Django |

I had a need for a file storage system, which would keep the original file name in tact, no matter what. By default, Django’s FileField’s only allow you to base the directory name on the datetime. While this is good for the most part, you can still have duplicate file names if they are added on the same day.

So, after a few headaches, here’s what I call the UsefulFileField:

import os.path
import time
from django.db import models
 
class UsefulFileField(models.FileField):
    _path = None
 
    def get_filename(self, filename):
        f = os.path.join(self.get_directory_name(), os.path.basename(filename))
        return os.path.normpath(f)
 
    def get_directory_name(self):
        if self._path is None:
            self._path = os.path.normpath(self.upload_to % tuple(str(float(time.time())).split('.')))
        return self._path
 
class UsefulImageField(models.ImageField):
    _path = None
 
    def get_filename(self, filename):
        f = os.path.join(self.get_directory_name(), os.path.basename(filename))
        return os.path.normpath(f)
 
    def get_directory_name(self):
        if self._path is None:
            self._path = os.path.normpath(self.upload_to % tuple(str(float(time.time())).split('.')))
        return self._path

An example use:

class MyModel(models.Model):
    screenshot  = UsefulImageField(upload_to="screenshots/%s/%s/", blank=True, null=True)

View Comments Responses to "File Fields without Renaming Duplicates"

Subscribe to this topic with RSS or get the Trackback URL
Gulopine (Apr 11th):

This is one of many reasons I’m really looking forward to ticket #5361 being checked into trunk as soon as possible. What you’re working toward here would be quite simple (my apologies if the code doesn’t look right.

from django.core.filestorage.filesystem import FileSystemStorage

class UsefulFileStorage(FileSystemStorage):
def get_available_filename(self, filename):
# Leave the filename unmodified
return filename

Then when you want to use it in a model:

from django.db import models
from myapp.storage import UsefulFileStorage

class MyModel(models.Model):
screenshot = models.ImageField(upload_to=”screenshots/%s/%s/”, storage=UsefulFileStorage(), blank=True, null=True)

David (Apr 11th):

Mmm nice.

I ended up reworking my filefield’s and just using file = blah and calling .save(). The timestamp stuff was still causing too many directories, and I had to base it off the an id (similar to how we had done it at Curse).

It ends up being screenshots/%s/%s % divmod(id, 1000)

Leave A Reply

 Username (*required)

 Email Address (*private)

 Website (*optional)

Note: Comments moderation may be active so there is no need to resubmit your comment.
blog comments powered by Disqus