Jak wgrać plik w Django? [zamknięte]
chcesz poprawić to pytanie? Update the question so it edytując ten post.
Zamknięte 5 lat temu .
Popraw to pytanieJako 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ć?
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 adresemlocalhost: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.
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.
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/
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.
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 %}
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.
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.
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)
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)
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)
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