首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

【转载】django:设立上传文件夹

2012-08-02 
【转载】django:设置上传文件夹原文地址:http://plq168.blog.163.com/blog/static/53101462201093115050188/

【转载】django:设置上传文件夹

原文地址:http://plq168.blog.163.com/blog/static/53101462201093115050188/

参考于http://adil.2scomplement.com/2009/01/django-playing-with-upload_to-field/
?? ?django提供了两种字段类型models.FileField与models.ImageField,用于保存上传文件与图
象.这两类字段提供了一个参数'upload_to',用于定义上传文件保存的路径(完整的路径为settings.MEDIA_ROOT + upload_to).
运行时创建基于时间的文件夹
?? ?你可以使用参数upload_to,上传文件到一个基于文件时间的文件夹中.?? ?假如你要创建一个相册,要把图片传到名称包含年与月的文件夹中.
class Photo(models.Model):??original = models.ImageField(upload_to='album/%m-%Y/')
?? ?每次保存一个图片时,django会在MEDIA_ROOT/album/中创建一个'MM-YYYY'文件夹,用来保存图片.?? 使用django源码来说明实现方式:?? 在django/db/models/fields/fiels.py中?? class FileField(Field):?? ? ? ....?? ? ? def __init__(self,...,upload_to='',...):?? ? ? ? ? ...?? self.upload_to = upload_to?? ? ? ? ? if callable(upload_to):?? ? ? ? ? ? ? self.generate_filename = upload_to?? ? ? ? ? ...?? 说明:?? ? ? 如果upload_to是可执行的,则FileField的方法generate_filename的默认方法就会被覆盖
?? 保存时的操作:?? Class FileField(Field):?? ? ? ...?? ? ? def pre_save(self, model_instance, add):?? ? ? ? ? file = super(FileField, self).pre_save(model_instance, add) ?# file的类型是FieldFile?? ? ? ? ? if file and not file._committed:?? ? ? ? ? ? ? file.save(file.name, file, save=False)?? ? ? ? ? return file?? 而file中save的代码如下:?? class FieldFile(File):?? ? ? ...?? ? ? def save(...):?? ? ? ? ? name = self.field.generate_filename(self.instance, name)?? ? ? ? ? self.name = self.storage.save(name, content)?? ? ? ? ? ...??从以上代码看来,如果upload_to是可执行的,FieldFile的方法save会调用generate_filename方
法,但实际上是已替换为upload_to.如upload_to不能执行,就会执行FieldFile的方法save会调用
FileField的默认方法generate_filename方法.?? ?class FieldFile(Field):?? ? ? ?...?? ? ? ?def generate_filename(self, instance, filename):?? ? ? ? ? return os.path.join(self.get_directory_name(), self.get_filename(filename))
?? ? ? ?def get_directory_name(self):?? ? ? ? ? return os.path.normpath(force_unicode(datetime.datetime.now().strftime(smart_str(self.upload_to))))
?? ? ? ?def get_filename(self, filename):?? ? ? ? ? return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename)))
??上面的实例中,为了产生上传文件夹名,实际上是执行了get_directory_name,而这个函数中包含
了upload_to,把实际的数据代入后,文件名是由下面的代码计算出来的:datetime.datetime.now().strftime('album/%m-%Y/'),'%m-%Y'是时间格式符.
动态更改上传文件夹以下面的model为例:class MediaContent(models.Model):?? content_file = models.FileField()?? content_type = models.CharField(max_length=1,?? ? ?choices=(('I','Image'),('V','Video'),('A','Audio'),('D','Doc')))?? #other fields
MediaContent文件提供了各种媒体文件,如图象,视频,音频,文档与pdf文件.我要对这些媒体文件提供一致的操作,但不同的文件类型上传到不同的文件夹中.所以在保存MediaContent实例前需要更改upload_to.
使用一个callback作为upload_to
django可以让你提供一个callback作为upload_to值.这个回调函数有如下参数:?? 1) self ?MediaConten实例?? 2) instance 真正的FileField或ImageField实例(此处实际上是content_file)?? 3) filename 当保存文件时需要传递的文件名使用这个技术,按下面代码来实现:class MediaContent(models.Model):??content_file = models.FieldFile(upload_to=get_media_upload_to)??content_type = models.CharField(max_length=1,?? ?choices=(('I','Image'),('V','Video'),('A','Audio'),('D','Doc')))??#other fields
def get_media_upload_to(instance, filename):?? ?"""?? ?A simple way to return the full path ? ? ??? ?"""?? ?paths = { 'I':'images/', 'V':'videos/', 'A':'audio/', 'D':'documents'/ }?? ?return settings.MEDIA_ROOT + 'content/' + paths[instance.content_type] + filename每次调用media_content_object.content_file.save(filename, mem_file)时,get_media_upload_to就会被调用,你可以基于content_type来确定文件路径.
运行时修改upload_to
你可以设置upload_to为一个固定的值,然后在保存对象时更改为你要的位置def save_content(request):?? ?#if image?? ? ? ?MediContent._meta.get_field('content_file').upload_to='content/images/'?? ?#if video?? ? ? ?MediContent._meta.get_field('content_file').upload_to='content/videos/'?? ?#if audio?? ? ? ?MediContent._meta.get_field('content_file').upload_to='content/audios/'?? ?#if doc?? ? ? ?MediContent._meta.get_field('content_file').upload_to='content/documents/'?? ?#if pdf?? ? ? ?MediContent._meta.get_field('content_file').upload_to='content/acrobat/'?? ?#other types

热点排行