Mon 28 Apr 2008
Django-1.0-file-upload
Posted On Django At: 2008-09-15 16:40:19
原因
想通过 Django admin 做个简单的上传文件管理,遇到个问题。files = models.FileField(upload_to=('files')) 默认是把所有的文件都保存在同一个目录 files 下面,我想通过types来判断不同的类型保存到不同目录下,像这样的结构: files/types/filename.
表结构:
class Car(models.Model):
name = models.CharField(max_length=255)
types = models.CharField(max_length=255)
files = models.FileField(upload_to=('files'))
分析问题
如果upload_to可以解决问题最好不过,如果不行就只能在数据库保存是进行干扰,再不行就放弃admin自己做管理页面。
解决问题
django 1.0 已经支持 upload_to参数使用函数,该函数约定有两个参数,一个是对象实例,一个是文件名,返回一个文件名。
- def upload_to(instance,filename):
- return 'files/%s/%s' % (instance.types,filename)
可以参考原文:
FileField.upload_to
A local filesystem path that will be appended to your MEDIA_ROOT setting to determine the value of the url attribute.
This path may contain strftime formatting, which will be replaced by the date/time of the file upload (so that uploaded files don't fill up the given directory).
Changed in Django 1.0.
This may also be a callable, such as a function, which will be called to obtain the upload path, including the filename. This callable must be able to accept two arguments, and return a Unix-style path (with forward slashes) to be passed along to the storage system. The two arguments that will be passed are:
instance
An instance of the model where the FileField is defined. More specifically, this is the particular instance where the current file is being attached.
In most cases, this object will not have been saved to the database yet, so if it uses the default AutoField, it might not yet have a value for its primary key field.
filename
The filename that was originally given to the file. This may or may not be taken into account when determining the final destination path.
Also has one optional argument.
原文链接: http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.FileField.upload_to
最终代码
from django.db import models
from django.forms import ModelForm
from django.contrib import admin
def files_path(instance, filename):
return 'files/%s/%s' % (instance.types, filename)
class Car(models.Model):
name = models.CharField(max_length=255)
types = models.CharField(max_length=255)
files = models.FileField(upload_to=files_path)
def __unicode__(self):
return u'%s' % self.name
class CarAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'types', 'files', 'file_url', 'file_path')
def file_url(self, obj):
return obj.files.url
file_url.short_description = 'files url'
def file_path(self, obj):
return obj.files.path
file_path.short_description = 'files path'
admin.site.register(Car, CarAdmin)
感谢
非常感谢 Python-cn 用户组兄弟们的耐心解答。讨论地址: http://groups.google.com/group/python-cn/browse_thread/thread/0e678f1a6ce07d49#
borderj # gmail.com (Gtalk)
http://www.b0rder.com