Besoin d'un exemple minimal de téléchargement de fichier Django [fermé]

en tant qu'internaute novice de Django, j'ai du mal à faire une application de téléchargement dans Django 1.3. Je n'ai pas pu trouver d'exemple/extrait à jour. Quelqu'un peut-il afficher un code d'exemple minimal mais complet (Model, View, Template) pour le faire?

591
demandé sur pnovotnak 2011-05-03 19:17:05

10 réponses

Phew, la documentation de Django n'a vraiment pas de bon exemple à ce sujet. J'ai passé plus de 2 heures pour déterrer tous les morceaux pour comprendre comment cela fonctionne. Avec cette connaissance, j'ai mis en œuvre un projet qui permet de télécharger des fichiers et de les afficher sous forme de liste. Pour télécharger la source du projet, visitez https://github.com/axelpale/minimal-django-file-upload-example ou le cloner:

> git clone https://github.com/axelpale/minimal-django-file-upload-example.git

mise à jour 2013-01-30: la source à GitHub a également la mise en œuvre pour Django 1.4 en plus de 1.3. Même s'il y a peu de changements, le tutoriel suivant est également utile pour 1.4.

mise à jour 2013-05-10: Implementation for Django 1.5 at GitHub. Modifications mineures dans la redirection urls.py et l'utilisation de la balise de modèle d'url dans la liste.HTML. Merci à hubert3 pour l'effort.

mise à jour 2013-12-07: Django 1.6 pris en charge sur GitHub. Une importation a changé en myapp/urls.py. Merci à Arthedian .

mise à jour 2015-03-17: Django 1.7 supporté à GitHub, grâce à aronysidoro .

mise à jour 2015-09-04: Django 1.8 supporté chez GitHub, grâce à nerogit .

Mise à jour 2016-07-03: Django 1.9 supporté à GitHub, grâce à daavve et nerogit

arborescence du Projet

un projet de base Django 1.3 avec une seule application et un seul média/ répertoire pour les téléchargements.

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. Paramètres: myproject/settings.py

pour télécharger et servir des fichiers, vous devez spécifier où Django stocke les fichiers téléchargés et à partir quelle URL Django leur sert. MEDIA_ROOT et MEDIA_URL sont en settings.py by default but they are empty. Voir les premières lignes de Django Managing Files pour plus de détails. N'oubliez pas de définir également la base de données et d'ajouter 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',
)

2. Modèle: myproject/myapp/models.py

ensuite, vous avez besoin d'un modèle avec un champ de champ. Ce champ particulier permet de stocker des fichiers, par exemple vers des supports/documents/2011/12/24/ basé sur la date actuelle et MEDIA_ROOT. Voir FileField de référence .

# -*- coding: utf-8 -*-
from django.db import models

class Document(models.Model):
    docfile = models.FileField(upload_to='documents/%Y/%m/%d')

3. Forme: myproject/myapp/forms.py

pour gérer le téléchargement correctement, vous avez besoin d'un formulaire. Cette forme n'a qu'un seul champ, mais c'est suffisant. Voir référence du formulaire pour plus de détails.

# -*- coding: utf-8 -*-
from django import forms

class DocumentForm(forms.Form):
    docfile = forms.FileField(
        label='Select a file',
        help_text='max. 42 megabytes'
    )

4. Vue: myproject/myapp/views.py

une vue où toute la magie se produit. Faites attention comment request.FILES sont manipulés. Pour moi, il était vraiment difficile de repérer le fait que request.FILES['docfile'] peut être sauvé aux modèles.FileField juste comme ça. La fonction save() du model gère automatiquement le stockage du fichier dans le système de fichiers.

# -*- 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. Adresse URL du projet: myproject/urls.py

Django ne sert pas MEDIA_ROOT par défaut. Ce serait dangereux dans un environnement de production. Mais en phase de développement, nous pourrions couper court. Faites attention à la dernière ligne. Cette ligne permet à Django de servir des fichiers à partir de MEDIA_URL. Cela ne fonctionne qu'en phase de développement.

voir django.conf.URL.statique.référence statique pour plus de détails. Voir aussi .

# -*- 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. Adresses URL des applications: myproject/myapp/urls.py

pour rendre la vue accessible, vous devez spécifier des urls pour elle. Rien de spécial ici.

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url

urlpatterns = patterns('myapp.views',
    url(r'^list/$', 'list', name='list'),
)

7. Modèle: monprojet/myapp/templates/myapp/liste.html

La dernière partie: modèle de liste et le formulaire de téléchargement ci-dessous. Le formulaire doit avoir l'attribut enctype défini à "multipart / form-data" et la méthode définie à "post" pour rendre le téléchargement à Django possible. Voir documentation de téléchargement de fichiers pour plus de détails.

le champ de fichier a beaucoup d'attributs qui peuvent être utilisés dans les gabarits. E. g. {{ document.d'un document.url }} et {{document.docfile.nom }} comme dans le modèle. En savoir plus sur ceux-ci dans en utilisant des fichiers dans l'article modèles et la documentation D'objet de fichier .

<!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. Initialiser

lancez simplement syncdb et runserver.

> cd myproject
> python manage.py syncdb
> python manage.py runserver

résultats

Enfin, tout est prêt. Par défaut, L'environnement de développement de Django la liste des documents téléchargés peut être consultée à localhost:8000/list/ . Aujourd'hui, les fichiers sont téléchargés vers le /chemin/vers/monprojet/media/documents/2011/12/17/ et peut être ouvert à partir de la liste.

j'espère que cette réponse vous aidera à quelqu'un comme beaucoup comme il m'aurait aidée.

1203
répondu Akseli Palén 2017-05-23 12:02:58

Généralement parlant quand vous essayez de 'juste obtenir un exemple de travail' il est préférable de 'juste commencer à écrire du code'. Il n'y a pas de code ici pour vous aider, donc répondre à la question nous fait beaucoup plus de travail.

si vous voulez récupérer un fichier, vous avez besoin de quelque chose comme ça dans un fichier html quelque part:

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

qui vous donnera le bouton browse, un bouton upload pour lancer l'action (soumettre le formulaire) et noter l'enctype so Django sait vous donner request.FILES

dans une vue quelque part, vous pouvez accéder au fichier avec

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

Il ya une énorme quantité d'informations dans le fichier upload docs

je vous recommande de lire attentivement la page et il suffit de commencer à écrire le code - puis revenir avec des exemples et empiler des traces quand il ne fonctionne pas.

60
répondu Henry 2011-05-03 15:25:48

Démo

mise à Jour de Akseli Palén la réponse de . voir le GitHub repo , œuvres avec Django 2

Un minimum de Django upload de fichier exemple

1. Créer un projet django

Exécuter startproject::

$ django-admin.py startproject sample

maintenant un dossier ( échantillon ) est créé::

sample/
  manage.py
  sample/
    __init__.py
    settings.py
    urls.py
    wsgi.py 

2. créer une application

créer une application::

$ cd sample
$ python manage.py startapp uploader

Maintenant un dossier( uploader ) avec ces fichiers sont créés::

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

3. Mise à jour settings.py

sur sample/settings.py ajouter 'uploader.apps.UploaderConfig' à INSTALLED_APPS et ajouter MEDIA_ROOT et MEDIA_URL , c'est-à-dire:

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

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

4. Mise à jour urls.py

dans sample/urls.py ajouter::

...<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.home, name='imageupload'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

5. Mise à jour models.py

mise à jour uploader/models.py ::

from django.db import models
from django.forms import ModelForm

class Upload(models.Model):
    pic = models.FileField(upload_to="images/")    
    upload_date=models.DateTimeField(auto_now_add =True)

# FileUpload form class.
class UploadForm(ModelForm):
    class Meta:
        model = Upload
        fields = ('pic',)

6. Mise à jour views.py

mise à jour uploader/views.py ::

from django.shortcuts import render
from uploader.models import UploadForm,Upload
from django.http import HttpResponseRedirect
from django.urls import reverse
# Create your views here.
def home(request):
    if request.method=="POST":
        img = UploadForm(request.POST, request.FILES)       
        if img.is_valid():
            img.save()  
            return HttpResponseRedirect(reverse('imageupload'))
    else:
        img=UploadForm()
    images=Upload.objects.all().order_by('-upload_date')
    return render(request,'home.html',{'form':img,'images':images})

7. créer des modèles

Créer un dossier modèles dans le dossier uploader , puis créez un fichier maison.html , c'est à dire sample/uploader/templates/home.html ::

<div style="padding:40px;margin:40px;border:1px solid #ccc">
    <h1>picture</h1>
    <form action="#" method="post" enctype="multipart/form-data">
        {% csrf_token %} {{form}} 
        <input type="submit" value="Upload" />
    </form>
    {% for img in images %}
        {{forloop.counter}}.<a href="{{ img.pic.url }}">{{ img.pic.name }}</a>
        ({{img.upload_date}})<hr />
    {% endfor %}
</div>

8. Synchroniser la base de données

Synchroniser la base de données et runserver::

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

visit http://localhost.com:8000

54
répondu simple_human 2018-07-11 01:00:28

je dois dire que je trouve la documentation à django confuse. Aussi pour l'exemple le plus simple pourquoi sont des formes d'être mentionné? L'exemple que j'ai eu à travailler dans le views.py est :-

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()

le fichier html ressemble au code ci-dessous, bien que cet exemple ne télécharge qu'un fichier et que le code pour enregistrer les fichiers en gère beaucoup: -

<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>

ces exemples ne sont pas mon code, ils ont été tirés de deux autres exemples que j'ai trouvés. Je suis un parent débutant à django donc il est très probable que je manque un point clé.

22
répondu jimscafe 2013-04-07 20:28:08

s'Étendant sur de Henry exemple :

import tempfile
import shutil

FILE_UPLOAD_DIR = '/home/imran/uploads'

def handle_uploaded_file(source):
    fd, filepath = tempfile.mkstemp(prefix=source.name, dir=FILE_UPLOAD_DIR)
    with open(filepath, 'wb') as dest:
        shutil.copyfileobj(source, dest)
    return filepath

vous pouvez appeler cette fonction handle_uploaded_file de votre point de vue avec l'objet fichier téléchargé. Cela permettra de sauvegarder le fichier avec un nom unique (préfixé avec le nom du fichier d'origine téléchargé) dans le système de fichiers et de retourner le chemin complet du fichier sauvegardé. Vous pouvez enregistrer le chemin dans la base de données, et faire quelque chose avec le fichier plus tard.

14
répondu Imran 2017-05-23 11:47:29

j'avais également l'exigence similaire. La plupart des exemples sur net demandent de créer des modèles et des formes que je ne voulais pas utiliser. Voici mon code final.

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

et en HTML pour télécharger j'ai écrit:

{% 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 %}

suit le HTML qui affiche le contenu du fichier:

{% block content %}
    <h3>File uploaded successfully</h3>
    {{file.name}}
    </br>content = {{contentOfFile}}
{% endblock %}
10
répondu chetan pawar 2014-11-10 02:16:55

ici, il peut vous aider: créer un champ fichier dans votre models.py

pour télécharger le fichier(dans votre admin.py):

def save_model(self, request, obj, form, change):
    url = "http://img.youtube.com/vi/%s/hqdefault.jpg" %(obj.video)
    url = str(url)

    if url:
        temp_img = NamedTemporaryFile(delete=True)
        temp_img.write(urllib2.urlopen(url).read())
        temp_img.flush()
        filename_img = urlparse(url).path.split('/')[-1]
        obj.image.save(filename_img,File(temp_img)

et utilisez ce champ dans votre modèle.

10
répondu Vijesh Venugopal 2017-01-25 04:40:16

vous pouvez vous référer à des exemples de serveur dans Fin Uploader, qui a la version django. https://github.com/FineUploader/server-examples/tree/master/python/django-fine-uploader

c'est très élégant et le plus important de tous, il offre featured js lib. Template n'est pas inclus dans server-examples, mais vous pouvez trouver demo sur son site web. Uploader fin: http://fineuploader.com/demos.html

django-fine-uploader

views.py

UploadView les dépêches de la poste et supprimer la demande pour les différents gestionnaires.

class UploadView(View):

    @csrf_exempt
    def dispatch(self, *args, **kwargs):
        return super(UploadView, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        """A POST request. Validate the form and then handle the upload
        based ont the POSTed data. Does not handle extra parameters yet.
        """
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_upload(request.FILES['qqfile'], form.cleaned_data)
            return make_response(content=json.dumps({ 'success': True }))
        else:
            return make_response(status=400,
                content=json.dumps({
                    'success': False,
                    'error': '%s' % repr(form.errors)
                }))

    def delete(self, request, *args, **kwargs):
        """A DELETE request. If found, deletes a file with the corresponding
        UUID from the server's filesystem.
        """
        qquuid = kwargs.get('qquuid', '')
        if qquuid:
            try:
                handle_deleted_file(qquuid)
                return make_response(content=json.dumps({ 'success': True }))
            except Exception, e:
                return make_response(status=400,
                    content=json.dumps({
                        'success': False,
                        'error': '%s' % repr(e)
                    }))
        return make_response(status=404,
            content=json.dumps({
                'success': False,
                'error': 'File not present'
            }))

forms.py

class UploadFileForm(forms.Form):

    """ This form represents a basic request from Fine Uploader.
    The required fields will **always** be sent, the other fields are optional
    based on your setup.
    Edit this if you want to add custom parameters in the body of the POST
    request.
    """
    qqfile = forms.FileField()
    qquuid = forms.CharField()
    qqfilename = forms.CharField()
    qqpartindex = forms.IntegerField(required=False)
    qqchunksize = forms.IntegerField(required=False)
    qqpartbyteoffset = forms.IntegerField(required=False)
    qqtotalfilesize = forms.IntegerField(required=False)
    qqtotalparts = forms.IntegerField(required=False)
9
répondu Jiawei Dai 2015-11-30 13:02:20

pas sûr s'il y a des inconvénients à cette approche, mais encore plus minime, en views.py:

entry = form.save()

# save uploaded file
if request.FILES['myfile']:
    entry.myfile.save(request.FILES['myfile']._name, request.FILES['myfile'], True)
5
répondu PhoebeB 2014-09-08 11:14:21

j'ai fait face au même problème, et résolu par le site admin django.

# models
class Document(models.Model):
    docfile = models.FileField(upload_to='documents/Temp/%Y/%m/%d')

    def doc_name(self):
        return self.docfile.name.split('/')[-1] # only the name, not full path

# admin
from myapp.models import Document
class DocumentAdmin(admin.ModelAdmin):
    list_display = ('doc_name',)
admin.site.register(Document, DocumentAdmin)
0
répondu hlpmee 2014-05-14 06:58:03