作为 Django 的新手,我很难在 Django 1.3 中制作上传应用程序。我找不到任何最新的示例/片段。有人可以发布一个最小但完整的(模型、视图、模板)示例代码吗?
唷,Django 文档真的没有很好的例子。我花了 2 个多小时来挖掘所有的碎片以了解它是如何工作的。有了这些知识,我实现了一个项目,可以上传文件并将它们显示为列表。要下载项目的源代码,请访问https://github.com/axelpale/minimal- django-file-upload-example或克隆它:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git
2013-01-30 更新: GitHub 上的源代码除了 1.3 之外还实现了 Django 1.4。即使更改很少,以下教程对 1.4 也很有用。
2013-05-10 更新: 在 GitHub 上实现 Django 1.5。urls.py 中的重定向和 list.html 中 url 模板标签的使用的微小变化。感谢hubert3的努力。
2013-12-07 更新: GitHub 支持 Django 1.6。在 myapp/urls.py 中更改了一项导入。感谢Arthedian。
2015-03-17 更新: GitHub 支持 Django 1.7,感谢aronysidoro。
2015-09-04 更新: GitHub 支持 Django 1.8,感谢nerogit。
2016-07-03 更新: GitHub 支持 Django 1.9,感谢daavve和nerogit
一个基本的 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
要上传和提供文件,您需要指定 Django 存储上传文件的位置以及 Django 从哪个 URL 提供文件。MEDIA_ROOT 和 MEDIA_URL 默认在 settings.py 中,但它们是空的。有关详细信息,请参阅Django 管理文件中的第一行。记住还要设置数据库并将 myapp 添加到 INSTALLED_APPS
... import os BASE_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', )
接下来,您需要一个带有 FileField 的模型。此特定字段根据当前日期和 MEDIA_ROOT 将文件存储到例如 media/documents/2011/12/24/。请参阅FileField 参考。
# -*- coding: utf-8 -*- from django.db import models class Document(models.Model): docfile = models.FileField(upload_to='documents/%Y/%m/%d')
要很好地处理上传,您需要一个表单。此表单只有一个字段,但已足够。有关详细信息,请参阅表单文件字段参考。
# -*- coding: utf-8 -*- from django import forms class DocumentForm(forms.Form): docfile = forms.FileField( label='Select a file', help_text='max. 42 megabytes' )
所有魔术都发生的视图。注意如何request.FILES处理。对我来说,真的很难发现request.FILES['docfile']可以像这样保存到 models.FileField 的事实。模型的 save() 自动处理文件到文件系统的存储。
request.FILES
request.FILES['docfile']
# -*- coding: utf-8 -*- from django.shortcuts import render_to_response from django.template import RequestContext from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse from myproject.myapp.models import Document from myproject.myapp.forms import DocumentForm def 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) )
默认情况下,Django 不提供 MEDIA_ROOT 服务。这在生产环境中会很危险。但在开发阶段,我们可以缩短。注意最后一行。该行使 Django 能够从 MEDIA_URL 提供文件。这仅在开发阶段有效。
有关详细信息,请参阅django.conf.urls.static.static 参考。
# -*- coding: utf-8 -*- from django.conf.urls import patterns, include, url from django.conf import settings from django.conf.urls.static import static urlpatterns = patterns('', (r'^', include('myapp.urls')), ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
要使视图可访问,您必须为其指定 url。这里没什么特别的。
# -*- coding: utf-8 -*- from django.conf.urls import patterns, url urlpatterns = patterns('myapp.views', url(r'^list/$', 'list', name='list'), )
最后一部分:列表模板及其下方的上传表单。表单必须将 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>
只需运行syncdb 和runserver。
> cd myproject > python manage.py syncdb > python manage.py runserver
最后,一切准备就绪。在默认的 Django 开发环境中,上传文档的列表可以在localhost:8000/list/. 今天文件上传到 /path/to/myproject/media/documents/2011/12/17/ 并且可以从列表中打开。
localhost:8000/list/
我希望这个答案能帮助别人,就像它对我有帮助一样。