# -*- coding: UTF-8 -*- import os from random import randint from django.db import models from django.db.models.fields.files import FileField from django.utils.translation import ugettext_lazy as _ from django import forms from django.core.files.storage import FileSystemStorage class WhitelistedFileField(FileField): """Allows white listing of file extensions @var ext_whitelist: [tuple] with the endings of the Files e.g. (".wav",) """ def __init__(self, *args, **kwargs): """whitelisting http://www.djangosnippets.org/snippets/977/""" ext_whitelist = kwargs.pop("ext_whitelist") self.ext_whitelist = [i.lower() for i in ext_whitelist] super(WhitelistedFileField, self).__init__(*args, **kwargs) def clean(self, *args, **kwargs): """whitelisting""" data = super(WhitelistedFileField, self).clean(*args, **kwargs) filename = data.name ext = os.path.splitext(filename)[1] ext = ext.lower() if ext not in self.ext_whitelist: raise forms.ValidationError("Not allowed filetype!") else: return data class OverwritingFileSystemStorage(FileSystemStorage): """Overwrites the existing file with the target name Take care of the Django development stage see: http://groups.google.com/group/django-developers/browse_thread/thread/491619541ba6ac75 this is going to be updated in further Django versions """ def _save(self, name, *args): if self.exists(name): self.delete(name) return super(OverwritingFileSystemStorage, self)._save(name, *args) def get_available_name(self, name): return name AUDIO_FILE_ROOT= '/tmp/django' fs = OverwritingFileSystemStorage(location=AUDIO_FILE_ROOT) #change the originally MEDIA.ROOT WHITELIST = ('mp3',) def get_uploadTo_place(instance, naturalFilename): """Option for FileFields upload directory & name Prepares file subDirectory and fileName and returns the whole subpath based on: http://adil.2scomplement.com/2009/01/django-playing-with-upload_to-field/ """ fileType= instance.mytype try: #try to fetch the fileExtension fileExtension = naturalFilename.rsplit('.',1)[1] except IndexError: fileExtension = 'unknown' ###Associate admin-filetypes to a path and filetypes to a filename #'file_type':'path' subDirs = {'music' : "foo_music", 'ringtone': "foo_ringtone", 'others': "sounds",} #'file_type':'file_name' fileNames= {'others' : "%i_%s.%s" % (randint(1000,9999), fileType, fileExtension), } ###Lookup for concrete paths and filenames """prepare subDir""" if fileType in subDirs: subDir = subDirs[fileType] else: subDir = subDirs['others'] """prepare fileName""" if fileType in fileNames: fileName = fileNames[fileType] else: fileName = fileNames['others'] return "%s/%s" % (subDir, fileName) """USAGE""" CHOICE_filetype = ( ("music", _("music")), ("ringtone", _("ringtone")), ) class Foosystem(models.Model): mytype = models.CharField(_("audio type"), max_length=15, choices=CHOICE_filetype, ) audio_file = WhitelistedFileField(upload_to= get_uploadTo_place, \ storage = fs, \ ext_whitelist = WHITELIST, \ help_text = _("Accepted file types are")+ (': %s' % (', '.join(WHITELIST)) ), \ verbose_name = _("Audio File"))