Puh, die Django-Dokumentation hat wirklich kein gutes Beispiel für dieses Thema. Ich verbrachte über 2 Stunden zu graben, bis alle Stücke zu verstehen, wie dies funktioniert. Mit diesem Wissen habe ich ein Projekt implementiert, das es ermöglicht, Dateien hochzuladen und sie als Liste anzuzeigen. Um den Quellcode für das Projekt herunterzuladen, besuchen Sie https://github.com/axelpale/minimal-django-file-upload-example oder klonen Sie es:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git
Update 2013-01-30: Der Quelltext auf GitHub enthält neben 1.3 auch eine Implementierung für Django 1.4. Auch wenn es nur wenige Änderungen gibt, ist das folgende Tutorial auch für 1.4 nützlich.
Update 2013-05-10: Implementierung für Django 1.5 auf GitHub. Geringfügige Änderungen bei der Umleitung in urls.py und der Verwendung des url Template Tags in list.html. Dank an hubert3 für den Aufwand.
Update 2013-12-07: Django 1.6 wird auf GitHub unterstützt. Ein Import wurde in myapp/urls.py geändert. Der Dank geht an Arthedian .
Update 2015-03-17: Django 1.7 wird auf GitHub unterstützt, Dank an aronysidoro .
Update 2015-09-04: Django 1.8 wird auf GitHub unterstützt, Dank an nerogit .
Update 2016-07-03: Django 1.9 wird auf GitHub unterstützt, Dank an daavve y nerogit
Projektbaum
Ein einfaches Django 1.3 Projekt mit einer App und einem media/ Verzeichnis für Uploads.
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. Einstellungen: myproject/settings.py
Um Dateien hochzuladen und bereitzustellen, müssen Sie angeben, wo Django hochgeladene Dateien speichert und von welcher URL Django sie bereitstellt. MEDIA_ROOT und MEDIA_URL sind standardmäßig in settings.py enthalten, aber sie sind leer. Siehe die ersten Zeilen in Django Dateien verwalten für Einzelheiten. Vergessen Sie nicht, auch die Datenbank zu setzen und myapp zu INSTALLED_APPS hinzuzufügen
...
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',
)
2. Modell: myproject/myapp/models.py
Als nächstes benötigen Sie ein Modell mit einem FileField. Dieses spezielle Feld speichert Dateien z.B. in media/documents/2011/12/24/ basierend auf dem aktuellen Datum und MEDIA_ROOT. Siehe FileField-Referenz .
# -*- coding: utf-8 -*-
from django.db import models
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
3. Formular: myproject/myapp/forms.py
Um das Hochladen gut zu handhaben, brauchen Sie ein Formular. Dieses Formular hat nur ein Feld, aber das reicht aus. Siehe Formular FileField-Referenz für Details.
# -*- coding: utf-8 -*-
from django import forms
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file',
help_text='max. 42 megabytes'
)
4. Ansicht: myproject/myapp/views.py
Eine Aussicht, in der sich die ganze Magie abspielt. Achten Sie darauf, wie request.FILES
behandelt werden. Für mich war es wirklich schwer, die Tatsache zu erkennen, dass request.FILES['docfile']
kann einfach so in models.FileField gespeichert werden. Das Speichern der Datei im Dateisystem erfolgt automatisch mit save().
# -*- 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)
)
5. Projekt-URLs: myproject/urls.py
Django bedient MEDIA_ROOT standardmäßig nicht. Das wäre in einer Produktionsumgebung gefährlich. Aber in der Entwicklungsphase können wir das abkürzen. Achten Sie auf die letzte Zeile. Diese Zeile ermöglicht es Django, Dateien von MEDIA_URL auszuliefern. Dies funktioniert nur im Entwicklungsstadium.
Ver django.conf.urls.static.static-Referenz für Einzelheiten. Siehe auch diese Diskussion über die Bereitstellung von Mediendateien .
# -*- 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)
6. App-URLs: myproject/myapp/urls.py
Um die Ansicht zugänglich zu machen, müssen Sie Urls für sie angeben. Das ist nichts Besonderes.
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
urlpatterns = patterns('myapp.views',
url(r'^list/$', 'list', name='list'),
)
7. Vorlage: myproject/myapp/templates/myapp/list.html
Der letzte Teil: Vorlage für die Liste und das Upload-Formular darunter. Das Formular muss enctype-attribute auf "multipart/form-data" und method auf "post" gesetzt haben, um den Upload in Django zu ermöglichen. Siehe Dokumentation zum Hochladen von Dateien für Details.
Das FileField hat viele Attribute, die in Vorlagen verwendet werden können. Z.B. {{ document.docfile.url }} und {{ document.docfile.name }} wie in der Vorlage. Mehr über diese Attribute finden Sie in Verwendung von Dateien in Modellen Artikel y Die Dokumentation zum File-Objekt .
<!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. Initialisieren Sie
Führen Sie einfach syncdb und runserver aus.
> cd myproject
> python manage.py syncdb
> python manage.py runserver
Ergebnisse
Endlich ist alles fertig. In der Standard-Django-Entwicklungsumgebung kann die Liste der hochgeladenen Dokumente unter folgender Adresse eingesehen werden localhost:8000/list/
. Heute werden die Dateien nach /pfad/zu/myproject/media/documents/2011/12/17/ hochgeladen und können von der Liste aus geöffnet werden.
Ich hoffe, diese Antwort hilft jemandem so sehr, wie sie mir geholfen hätte.