745 Stimmen

Wie lädt man eine Datei in Django hoch?

Als Neuling in Django habe ich Schwierigkeiten, eine Upload-App in Django 1.3 zu erstellen. Ich konnte keine aktuellen Beispiele/Snippets finden. Kann jemand eine minimale, aber vollständige (Model, View, Template) Beispielcode, dies zu tun posten?

1367voto

Akseli Palén Punkte 25741

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.

11 Stimmen

Ich habe die Stelle in den Django-Dokumenten gefunden, die Datei-Uploads zeigt. Das Beispiel in dieser Antwort ist hervorragend, aber die Informationen in den Django-Dokumenten werden mit neuen Versionen auf dem neuesten Stand gehalten. docs.djangoproject.com/de/dev/topics/http/file-uploads

0 Stimmen

@TaiwanGrapefruitTea Jetzt gibt es auch eine Implementierung für Django 1.4 auf GitHub. Vielleicht sehen wir in Zukunft Implementierungen für neuere Versionen :)

1 Stimmen

Das Beispiel funktioniert nicht für Django "1.5". In der HTML {% url list %} wird {% url "list" %} .

96voto

suhailvs Punkte 17111

Demo

Siehe die Github-Repository , funktioniert mit Django 3

Ein minimales Django-Datei-Upload-Beispiel

1. Erstellen Sie ein Django-Projekt

Starten Sie startproject::

$ django-admin.py startproject sample

jetzt ein Ordner( Muster ) erstellt wird.

2. eine App erstellen

Eine App erstellen::

$ cd sample
$ python manage.py startapp uploader

Jetzt ein Ordner( uploader ) mit diesen Dateien erstellt werden::

uploader/
  __init__.py
  admin.py
  app.py
  models.py
  tests.py
  views.py
  migrations/
    __init__.py

3. Einstellungen.py aktualisieren

Auf sample/settings.py hinzufügen. 'uploader' a INSTALLED_APPS und hinzufügen MEDIA_ROOT y MEDIA_URL , d.h.::

INSTALLED_APPS = [
    'uploader',
    ...<other apps>...      
]

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

4. urls.py aktualisieren

in sample/urls.py hinzufügen::

...<other imports>...
from django.conf import settings
from django.conf.urls.static import static
from uploader import views as uploader_views

urlpatterns = [
    ...<other url patterns>...
    path('', uploader_views.UploadView.as_view(), name='fileupload'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

5. models.py aktualisieren

Update uploader/models.py ::

from django.db import models
class Upload(models.Model):
    upload_file = models.FileField()    
    upload_date = models.DateTimeField(auto_now_add =True)

6. views.py aktualisieren

Update uploader/views.py ::

from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .models import Upload
class UploadView(CreateView):
    model = Upload
    fields = ['upload_file', ]
    success_url = reverse_lazy('fileupload')
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['documents'] = Upload.objects.all()
        return context

7. Vorlagen erstellen

Einen Ordner erstellen sample/uploader/templates/uploader

Eine Datei erstellen upload_form.html dh sample/uploader/templates/uploader/upload_form.html ::

<div style="padding:40px;margin:40px;border:1px solid #ccc">
    <h1>Django File Upload</h1>
    <form method="post" enctype="multipart/form-data">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">Submit</button>
    </form><hr>
    <ul>
    {% for document in documents %}
        <li>
            <a href="{{ document.upload_file.url }}">{{ document.upload_file.name }}</a>
            <small>({{ document.upload_file.size|filesizeformat }}) - {{document.upload_date}}</small>
        </li>
    {% endfor %}
    </ul>
</div>

8. Syncronisierung der Datenbank

Syncronisieren Sie Datenbank und Runserver::

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver

besuchen Sie http://localhost:8000/

3 Stimmen

Perfekt bis auf die letzte Zeile - sollte lauten localhost.com:8000/upload > Dies funktionierte für Django 1.6 und Python 3.3.

5 Stimmen

+1 für wiederverwendbare django app design pattern

1 Stimmen

Akseli verwendete eine FileField während Suhail ein ImageField Könnte mir jemand bitte die Auswahlmöglichkeiten erklären?

93voto

Henry Punkte 6292

Wenn Sie versuchen, ein funktionierendes Beispiel zu erstellen, ist es im Allgemeinen am besten, einfach mit dem Schreiben von Code zu beginnen. Hier gibt es keinen Code, mit dem wir Ihnen helfen können, so dass die Beantwortung der Frage für uns viel mehr Arbeit bedeutet.

Wenn Sie eine Datei abrufen wollen, müssen Sie so etwas irgendwo in einer HTML-Datei unterbringen:

<form method="post" enctype="multipart/form-data">
    <input type="file" name="myfile" />
    <input type="submit" name="submit" value="Upload" />
</form>

Dadurch erhalten Sie den Browse-Button, einen Upload-Button, um die Aktion zu starten (das Formular zu übermitteln) und den Enctype zu notieren, damit Django weiß, dass es Ihnen request.FILES

In einer Ansicht können Sie irgendwo auf die Datei mit

def myview(request):
    request.FILES['myfile'] # this is my file

Es gibt eine große Menge an Informationen in der Datei-Upload-Dokumente

Ich empfehle Ihnen, die Seite gründlich zu lesen und einfach anfangen, Code zu schreiben - und dann mit Beispielen und Stack Traces zurückkommen, wenn es nicht funktioniert.

10 Stimmen

Danke, Henry. Eigentlich habe ich die Doku gelesen und etwas Code geschrieben, aber da die Doku einige Lücken hat (z.B. "from somewhere import handle_uploaded_file") und mein Code fehlerhaft war, dachte ich, dass es viel besser wäre, wenn ich von einem funktionierenden Beispiel ausgehen könnte.

31 Stimmen

Stimme mit qliq überein. Ein einfaches Arbeitsbeispiel ist der effizienteste Weg, um Neulingen den Einstieg zu erleichtern, nicht die Dokumentation.

14 Stimmen

En enctype="multipart/form-data" was ich brauchte, damit das funktioniert, danke!

33voto

jimscafe Punkte 1031

Ich muss sagen, dass ich die Dokumentation bei django verwirrend finde. Auch für das einfachste Beispiel, warum werden Formulare erwähnt? Das Beispiel, das ich in der views.py zum Laufen gebracht habe, ist :-

for key, file in request.FILES.items():
    path = file.name
    dest = open(path, 'w')
    if file.multiple_chunks:
        for c in file.chunks():
            dest.write(c)
    else:
        dest.write(file.read())
    dest.close()

Die Html-Datei sieht wie der folgende Code aus, obwohl in diesem Beispiel nur eine Datei hochgeladen wird und der Code zum Speichern der Dateien mehrere Dateien verarbeitet :-

<form action="/upload_file/" method="post" enctype="multipart/form-data">{% csrf_token %}
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>

Diese Beispiele sind nicht von mir, sondern wurden von zwei anderen Beispielen übernommen, die ich gefunden habe. Ich bin ein relativer Anfänger in Django, so ist es sehr wahrscheinlich, dass ich einige wichtige Punkte übersehen.

4 Stimmen

+1 für die Nichtverwendung eines FileField und eine model.Form . Für Anfänger (und für triviale Aufgaben) ist die manuelle Verarbeitung von hochgeladenen Dateien wie oben gezeigt weniger verwirrend.

1 Stimmen

Dest = open(path, 'wb') wenn Datei mit Bytes schreiben

24voto

chetan pawar Punkte 485

Ich hatte auch eine ähnliche Anforderung. Die meisten Beispiele im Netz verlangen die Erstellung von Modellen und Formularen, die ich nicht verwenden wollte. Hier ist mein endgültiger Code.

if request.method == 'POST':
    file1 = request.FILES['file']
    contentOfFile = file1.read()
    if file1:
        return render(request, 'blogapp/Statistics.html', {'file': file1, 'contentOfFile': contentOfFile})

Und in HTML zum Hochladen habe ich geschrieben:

{% block content %}
    <h1>File content</h1>
    <form action="{% url 'blogapp:uploadComplete'%}" method="post" enctype="multipart/form-data">
         {% csrf_token %}
        <input id="uploadbutton" type="file" value="Browse" name="file" accept="text/csv" />
        <input type="submit" value="Upload" />
    </form>
    {% endblock %}

Es folgt der HTML-Code, der den Inhalt der Datei anzeigt:

{% block content %}
    <h3>File uploaded successfully</h3>
    {{file.name}}
    </br>content = {{contentOfFile}}
{% endblock %}

0 Stimmen

Gut, denn manchmal möchte man nur den Inhalt der Datei verwenden und nicht den Upload speichern...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X