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


En tant que débutant à Django, j'ai du mal à faire une application de téléchargement dans Django 1.3. Je n'ai trouvé aucun exemple / extrait à jour. Est-ce que quelqu'un peut poster un code d'exemple minimal mais complet (Model, View, Template) pour le faire?


583
2018-05-03 15:17


origine


Réponses:


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

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

Mise à jour 2013-01-30: La source de GitHub a également implémenté 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: Implémentation de Django 1.5 sur GitHub. Modifications mineures de la redirection dans urls.py et utilisation de la balise de modèle d'URL dans list.html. Grâce à hubert3 pour l'effort.

Mise à jour 2013-12-07: Django 1.6 pris en charge à GitHub. Une importation a été modifiée dans myapp / urls.py. Merci à Arthédien.

Mise à jour 2015-03-17: Django 1.7 pris en charge à GitHub, grâce à Aronysidoro.

Mise à jour 2015-09-04: Django 1.8 pris en charge sur GitHub, grâce à nerogit.

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

Arbre de projet

Un projet Django 1.3 de base avec une application unique et un répertoire média / media 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 distribuer des fichiers, vous devez spécifier où Django stocke les fichiers téléchargés et à partir de quelle URL Django les sert. MEDIA_ROOT et MEDIA_URL sont dans settings.py par défaut mais ils sont vides. Voir les premières lignes dans Django Gérer des fichiers pour plus de détails. N'oubliez pas de définir 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 FileField. Ce champ particulier stocke des fichiers, par ex. à media / documents / 2011/12/24 / basé sur la date actuelle et MEDIA_ROOT. Voir Référence FileField.

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

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

3. Formulaire: myproject / myapp / forms.py

Pour gérer le téléchargement correctement, vous avez besoin d'un formulaire. Ce formulaire n'a qu'un seul champ mais c'est suffisant. Voir Form FileField référence 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. Voir: myproject / myapp / views.py

Une vue où toute la magie se passe. Faites attention comment request.FILES sont manipulés. Pour moi, c'était vraiment difficile de repérer le fait que request.FILES['docfile'] peut être enregistré sur models.FileField juste comme ça. Le save () du modèle 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. URL du projet: myproject / urls.py

Django ne sert pas MEDIA_ROOT par défaut. Ce serait dangereux dans l'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 depuis MEDIA_URL. Cela ne fonctionne que dans le stade de développement.

Voir django.conf.urls.static.static référence pour plus de détails. Voir également cette discussion sur le service des fichiers multimédias.

# -*- 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. URL de l'application: myproject / myapp / urls.py

Pour rendre l'affichage accessible, vous devez spécifier des URL pour cela. 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: myproject / myapp / templates / myapp / list.html

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

FileField possède de nombreux attributs pouvant être utilisés dans les modèles. Par exemple. {{document.docfile.url}} et {{document.docfile.name}} comme dans le modèle. En savoir plus sur ces derniers dans Utilisation de fichiers dans l'article des modèles et La documentation de l'objet 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

Il suffit de lancer syncdb et runserver.

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

Résultats

Finalement, tout est prêt. Sur l'environnement de développement Django par défaut, la liste des documents téléchargés peut être vue à localhost:8000/list/. Aujourd'hui, les fichiers sont téléchargés dans / path / to / myproject / media / documents / 2011/12/17 / et peuvent être ouverts depuis la liste.

J'espère que cette réponse aidera quelqu'un autant qu'elle m'aurait aidé.


1196
2017-12-17 01:59



D'une manière générale, lorsque vous essayez d'obtenir un exemple concret, il vaut mieux simplement commencer à écrire du code. Il n'y a pas de code ici pour vous aider, alors cela rend beaucoup plus de travail pour nous.

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>

Cela vous donnera le bouton de navigation, un bouton de téléchargement pour lancer l'action (soumettez le formulaire) et notez l'enctype que 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 y a énormément d'informations dans le fichiers de téléchargement de fichiers

Je vous recommande de lire la page à fond et il suffit de commencer à écrire du code - Puis revenez avec des exemples et des traces de pile quand ça ne marche pas.


57
2018-05-03 15:25



Démo

Mise à jour de La réponse d'Akseli Palén. voir le github repo, marche avec Django 2

Un exemple de téléchargement de fichier Django minimal

1. Créez un projet django

Exécutez 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. Mettre à 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. Mettre à 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. Mettre à jour models.py

mettre à 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. Mettre à jour views.py

mettre à 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 home.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

Syncronize database et runserver ::

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

visite http://localhost.com:8000


51
2018-06-05 17:10



Je dois dire que je trouve la documentation de django déroutante. Aussi pour l'exemple le plus simple, pourquoi les formes sont-elles mentionnées? 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 télécharge seulement un fichier et le code pour enregistrer les fichiers 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é obtenus à partir de deux autres exemples que j'ai trouvés. Je suis un débutant relatif à django donc il est très probable que je manque un point clé.


22
2018-06-07 12:11



Prolonger sur L'exemple de Henry:

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 ça handle_uploaded_file fonctionner à partir de votre vue avec l'objet fichier téléchargé. Cela enregistrera le fichier avec un nom unique (préfixé par le nom de fichier du fichier téléchargé original) dans le système de fichiers et retournera 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
2018-05-03 15:42



Ici, cela peut vous aider:  créez un champ de fichier dans votre fichier 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 aussi ce champ dans votre template.


10
2017-10-20 10:39



J'ai également eu la même exigence. La plupart des exemples sur Internet demandent de créer des modèles et de créer 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 %}

Voici le code HTML qui affiche le contenu du fichier:

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

9
2017-11-10 02:16



Vous pouvez vous référer aux exemples de serveur dans Fine 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 fournit en vedette js lib. Le modèle n'est pas inclus dans les exemples de serveur, mais vous pouvez trouver une démonstration sur son site Web. Fine Uploader: http://fineuploader.com/demos.html

django-fine-uploader

views.py

UploadView envoie les messages et supprime la demande aux gestionnaires respectifs.

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
2018-04-07 04:35