ew,Django文档确实没有很好的例子。我花了2个多小时来挖掘所有内容,以了解其工作原理。有了这些知识,我实现了一个项目,该项目可以上传文件并将其显示为列表。要下载该项目的源代码,请访问https://github.com/axelpale/minimal-django-file-upload-example或克隆它:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git
GitHub上的源代码除了1.3之外,还实现了Django 1.4。尽管变化不大,但以下教程对1.4也很有用。
项目树
一个基本的Django 1.3项目,具有单个应用程序和用于上载的media /目录。
minimal-django-file-upload-example/ src/ myproject/ database/ sqlite.db media/ myapp/ templates/ myapp/ list.html forms.py models.py urls.py views.py __init__.py manage.py settings.py urls.py
1.设置:myproject / settings.py
要上传和提供文件,你需要指定Django在何处存储上传的文件,以及Django从哪些URL提供文件。默认情况下,MEDIA_ROOT和MEDIA_URL位于settings.py中,但它们为空。有关详细信息,请参见Django管理文件中的第一行。记住还要设置数据库并将myapp添加到INSTALLED_APPS
...import osbase_DIR = os.path.dirname(os.path.dirname(__file__))...DATAbaseS = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(base_DIR, 'database.sqlite3'), 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', }}...MEDIA_ROOT = os.path.join(base_DIR, 'media')MEDIA_URL = '/media/'...INSTALLED_APPS = ( ... 'myapp',)2.模型:myproject / myapp / models.py
接下来,你需要一个带有FileField的模型。该特定字段基于当前日期和MEDIA_ROOT将文件存储到例如media / documents / 2011/12/24 /。。
# -*- coding: utf-8 -*-from django.db import modelsclass document(models.Model): docfile = models.FileField(upload_to='documents/%Y/%m/%d')
3.表格:myproject / myapp / forms.py
为了更好地处理上传,你需要一个表格。这种形式只有一个字段,但是就足够了。有关详细信息,请参见表单FileField参考。
# -*- coding: utf-8 -*-from django import formsclass documentForm(forms.Form): docfile = forms.FileField( label='Select a file', help_text='max. 42 megabytes' )
4.查看:myproject / myapp / views.py
所有魔术发生的视图。注意如何
request.FILES处理。对我来说,真的很难发现
request.FILES['docfile']可以像这样保存到
models.FileField的事实。模型的save()自动处理文件到文件系统的存储。
# -*- coding: utf-8 -*-from django.shortcuts import render_to_responsefrom django.template import RequestContextfrom django.http import HttpResponseRedirectfrom django.core.urlresolvers import reversefrom myproject.myapp.models import documentfrom myproject.myapp.forms import documentFormdef list(request): # Handle file upload if request.method == 'POST': form = documentForm(request.POST, request.FILES) if form.is_valid(): newdoc = document(docfile = request.FILES['docfile']) newdoc.save() # Redirect to the document list after POST return HttpResponseRedirect(reverse('myapp.views.list')) else: form = documentForm() # A empty, unbound form # Load documents for the list page documents = document.objects.all() # Render list page with the documents and the form return render_to_response( 'myapp/list.html', {'documents': documents, 'form': form}, context_instance=RequestContext(request) )- Project URLs: myproject/urls.py
Django默认不提供MEDIA_ROOT。在生产环境中那将是危险的。但是在开发阶段,我们可以缩短。注意最后一行。该行使Django可以提供来自MEDIA_URL的文件。这仅在开发阶段有效。
# -*- coding: utf-8 -*-from django.conf.urls import patterns, include, urlfrom django.conf import settingsfrom django.conf.urls.static import staticurlpatterns = patterns('', (r'^', include('myapp.urls')),) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)- App URLs: myproject/myapp/urls.py
要使视图可访问,必须为其指定URL。这里没什么特别的。
# -*- coding: utf-8 -*-from django.conf.urls import patterns, urlurlpatterns = patterns('myapp.views', url(r'^list/$', 'list', name='list'),)- Template: myproject/myapp/templates/myapp/list.html
最后一部分:列表的模板及其下面的上传表单。表单必须将enctype-attribute设置为“ multipart / form-data”,并将方法设置为“ post”,才能上传到Django。有关详细信息,请参见文件上传文档。
FileField具有许多可以在模板中使用的属性。例如,如模板中的{{document.docfile.url}}和{{document.docfile.name}}。有关更多信息
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>Minimal Django File Upload Example</title> </head> <body> <!-- List of uploaded documents --> {% if documents %} <ul> {% for document in documents %} <li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a></li> {% endfor %} </ul> {% else %} <p>No documents.</p> {% endif %} <!-- Upload form. Note enctype attribute! --> <form action="{% url 'list' %}" method="post" enctype="multipart/form-data"> {% csrf_token %} <p>{{ form.non_field_errors }}</p> <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p> <p> {{ form.docfile.errors }} {{ form.docfile }} </p> <p><input type="submit" value="Upload" /></p> </form> </body></html> 8. Initialize
只需运行syncdb和runserver。
> cd myproject> python manage.py syncdb> python manage.py runserver
结果
最后,一切准备就绪。在默认的Django开发环境中,可以在上找到上载文档的列表localhost:8000/list/。今天,文件已上传到/ path / to / myproject / media / documents / 2011/12/17 /,并且可以从列表中打开。



