David Cramer's Blog

Python, Django, and Scale.

File Fields Without Renaming Duplicates

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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:
1
2
class MyModel(models.Model):
    screenshot  = UsefulImageField(upload_to="screenshots/%s/%s/", blank=True, null=True)

Comments