Jak wgrać plik w Django? [zamknięte]

zamknięte . To pytanie musi być bardziej skoncentrowane . Obecnie nie przyjmuje odpowiedzi.

chcesz poprawić to pytanie? Update the question so it edytując ten post.

Zamknięte 5 lat temu .

Popraw to pytanie

Jako początkujący Django, mam problemy z zrobieniem aplikacji wysyłającej w Django 1.3. Nie mogłem znaleźć żadnych aktualnych przykładów/fragmentów. Może ktoś zamieści minimum ale kompletne (Model, Widok, Szablon) przykładowy kod aby to zrobić?

Author: Underoos, 2011-05-03

10 answers

Phew, dokumentacja Django naprawdę nie ma dobrego przykładu na ten temat. Spędziłem ponad 2 godziny, aby wykopać wszystkie kawałki, aby zrozumieć, jak to działa. Dzięki tej wiedzy wdrożyłem projekt, który umożliwia przesyłanie plików i pokazywanie ich jako listy. Aby pobrać źródło projektu, odwiedź stronę https://github.com/axelpale/minimal-django-file-upload-example albo sklonować:

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

Aktualizacja 2013-01-30: źródło na Githubie ma również implementację dla Django 1.4 oprócz 1.3. Chociaż jest kilka zmian, poniższy samouczek jest również przydatny dla 1.4.

Aktualizacja 2013-05-10: implementacja dla Django 1.5 na Githubie. Drobne zmiany w przekierowaniach w urls.py i użycie znacznika szablonu URL w liście.html. Podziękowania dla hubert3 za wysiłek.

Aktualizacja 2013-12-07: Django 1.6 obsługiwane na Githubie. Jeden import zmieniony w myapp/urls.py. Thanks goes to Arthedian.

Aktualizacja 2015-03-17: Django 1.7 wspierane na Githubie, dzięki aronysidoro .

Aktualizacja 2015-09-04: Django 1.8 obsługiwane na Githubie, dzięki nerogit.

Aktualizacja 2016-07-03: Django 1.9 obsługiwane na Githubie, dzięki daavve i nerogit

Drzewo projektu

Podstawowy projekt Django 1.3 z pojedynczą aplikacją i katalogiem media / do przesyłania.

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. Ustawienia: myproject/settings.py

Aby wysyłać i serwować pliki, musisz określić, gdzie Django przechowuje przesłane pliki i z jakiego adresu URL Django je serwuje. MEDIA_ROOT i MEDIA_URL są w settings.py domyślnie, ale są puste. Zobacz pierwsze linie w Django zarządzające plikami po szczegóły. Pamiętaj również ustawić bazę danych i dodać myapp do 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. Model: myproject/myapp/models.py

Następnie potrzebujesz modelu z FileField. Ta szczególna dziedzina przechowuje pliki np. do mediów/dokumentów/2011/12/24/ na podstawie bieżącej daty i MEDIA_ROOT. Zobacz odniesienie do FileField .

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

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

3. Postać: myproject/myapp/forms.py

Aby dobrze obsłużyć upload, potrzebujesz formularza. Ten formularz ma tylko jedno pole, ale to wystarczy. Zobacz formularz filefield reference aby uzyskać szczegółowe informacje.

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

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

4. Widok: myproject/myapp/views.py

Widok, w którym dzieje się cała magia. Zwróć uwagę na sposób postępowania request.FILES. Dla mnie to było naprawdę trudno zauważyć, że request.FILES['docfile'] można zapisać na modelach.FileField tak po prostu. Funkcja save() modelu automatycznie obsługuje przechowywanie pliku w systemie plików.

# -*- 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 projektu: myproject/urls.py

Django domyślnie nie obsługuje MEDIA_ROOT. To byłoby niebezpieczne w środowisku produkcyjnym. Ale na etapie rozwoju możemy się skrócić. Zwróć uwagę na ostatnią linię. Ta linia umożliwia Django serwowanie plików z MEDIA_URL. To działa tylko w rozwoju scena.

Zobacz django.conf.URL.statyczne.statyczne odniesienie dla szczegółów. Zobacz także tę dyskusję na temat serwowania plików multimedialnych .

# -*- 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. Adresy URL aplikacji: myproject/myapp/urls.py

Aby Widok był dostępny, musisz podać adresy URL dla niego. Nic specjalnego.

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

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

7. Szablon: myproject / myapp / templates/myapp / list.html

Ostatnia część: szablon listy i formularz przesłania pod nią. Formularz musi mieć atrybut enctype Ustaw na "multipart / form-data" i metodę Ustaw na "post", aby upload do Django był możliwy. Zobacz plik wgrywa dokumentację po szczegóły.

FileField ma wiele atrybutów, które mogą być używane w szablonach. Np. {{document.docfile.url}} i {{ document.docfile.name }} jak w szablonie. Zobacz więcej na ten temat w używanie plików w modelach article i dokumentacja obiektu File .

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

Po prostu uruchom syncdb i runserver.

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

Wyniki

W końcu wszystko jest gotowe. W domyślnym środowisku programistycznym Django lista przesłanych dokumentów znajduje się pod adresem localhost:8000/list/. Obecnie pliki są przesyłane do /path / to / myproject / media / documents/2011/12/17/ i można je otworzyć z listy.

Mam nadzieję, że ta odpowiedź pomoże komuś tak samo, jak mnie.

 1299
Author: Akseli Palén,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:58

Ogólnie mówiąc, kiedy próbujesz "po prostu uzyskać działający przykład", najlepiej "po prostu zacząć pisać kod". Nie ma tu kodu, który mógłby ci pomóc, więc odpowiedź na to pytanie jest dla nas o wiele bardziej przydatna.

Jeśli chcesz pobrać plik, potrzebujesz czegoś takiego w pliku html:

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

To da ci przycisk Przeglądaj, przycisk wysyłania, aby rozpocząć akcję (Prześlij formularz) i zanotować enctype, aby Django wiedział, że da ci request.FILES

W zobacz gdzie możesz uzyskać dostęp do pliku za pomocą

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

Istnieje ogromna ilość informacji w dokumenty wysyłania plików

Zalecam dokładne przeczytanie strony i po prostu zacznij pisać kod - potem wróć z przykładami i stosuj ślady, gdy nie działa.

 80
Author: Henry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-03 15:25:48

Demo

Zobacz github repo , Działa z Django 3

Minimalny przykład przesłania pliku Django

1. Tworzenie projektu django

Uruchom startproject::

$ django-admin.py startproject sample

Teraz tworzony jest folder (sample ).

2. tworzenie aplikacji

Tworzenie aplikacji::

$ cd sample
$ python manage.py startapp uploader

Teraz tworzony jest folder (uploader) z tymi plikami::

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

3. Aktualizacja settings.py

On sample/settings.py add 'uploader' to INSTALLED_APPS and dodaj MEDIA_ROOT i MEDIA_URL, czyli:

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

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

4. Aktualizacja urls.py

W sample/urls.py dodaj::

...<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. Aktualizacja models.py

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. Aktualizacja views.py

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. tworzenie szablonów

Utwórz folder sample / uploader / templates / uploader

Utwórz plik upload_form.html ie 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. Syncronize database

Synchronizacja bazy danych i runserver::

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

Wizyta http://localhost:8000/

 76
Author: suhailvs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-20 17:02:29

Muszę powiedzieć, że dokumentacja w django jest myląca. Również dla najprostszego przykładu, dlaczego wymienia się formy? Przykład mam do pracy w views.py jest: -

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

Plik html wygląda jak poniższy kod, chociaż ten przykład przesyła tylko jeden plik, a kod do zapisania plików obsługuje wiele : -

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

Te przykłady nie są moim kodem, zostały wybrane z dwóch innych przykładów, które znalazłem. Jestem początkującym relatywnie django więc jest bardzo prawdopodobne, że brakuje mi jakiś kluczowy punkt.

 29
Author: jimscafe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-07 20:28:08

Ja też miałem podobne wymagania. Większość przykładów w sieci prosi o tworzenie modeli i formularzy, których nie chciałem używać. Oto mój ostatni kod.

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

A w HTML do uploadu napisałem:

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

Poniżej znajduje się HTML, który wyświetla zawartość pliku:

{% block content %}
    <h3>File uploaded successfully</h3>
    {{file.name}}
    </br>content = {{contentOfFile}}
{% endblock %}
 22
Author: chetan pawar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-10 02:16:55

Rozszerzenie na Przykład Henry ' ego :

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

Możesz wywołać tę funkcję handle_uploaded_file z widoku z przesłanym obiektem pliku. Spowoduje to zapisanie pliku o unikalnej nazwie (poprzedzonej nazwą oryginalnego przesłanego pliku) w systemie plików i zwróci pełną ścieżkę zapisanego pliku. Możesz zapisać ścieżkę w bazie danych i zrobić coś z plikiem później.

 17
Author: Imran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:29

Tutaj może Ci pomóc: Utwórz pole pliku w swoim models.py

Do wgrywania pliku(w Twoim 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)

I użyj tego pola również w szablonie.

 13
Author: Vijesh Venugopal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-25 04:40:16

Możesz odwoływać się do przykładów serwerów w Fine Uploader, który ma wersję django. https://github.com/FineUploader/server-examples/tree/master/python/django-fine-uploader

Jest bardzo elegancki i co najważniejsze, zapewnia funkcjonalny js lib. Szablon nie jest zawarty w server-examples, ale można znaleźć demo na jego stronie internetowej. Fine Uploader: http://fineuploader.com/demos.html

Django-fine-uploader

Views.py

UploadView wysyła żądanie post i delete do odpowiednich podmiotów obsługujących.

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)
 11
Author: Jiawei Dai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-30 13:02:20

Nie wiem, czy są jakieś wady tego podejścia, ale jeszcze bardziej minimalne, w views.py:

entry = form.save()

# save uploaded file
if request.FILES['myfile']:
    entry.myfile.save(request.FILES['myfile']._name, request.FILES['myfile'], True)
 8
Author: PhoebeB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-08 11:14:21

Spotkałem się z podobnym problemem i rozwiązałem go przez django admin site.

# 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
Author: hlpmee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-14 06:58:03