Jawaban:
Fiuh, dokumentasi Django benar-benar tidak punya contoh bagus tentang ini. Saya menghabiskan lebih dari 2 jam untuk menggali semua bagian untuk memahami cara kerjanya. Dengan pengetahuan itu saya mengimplementasikan proyek yang memungkinkan untuk mengunggah file dan menunjukkannya sebagai daftar. Untuk mengunduh sumber untuk proyek ini, kunjungi https://github.com/axelpale/minimal-django-file-upload-example atau klonkan:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git
Pembaruan 2013-01-30: Sumber di GitHub juga menerapkan untuk Django 1.4 selain 1.3. Meskipun ada beberapa perubahan, tutorial berikut ini juga berguna untuk 1.4.
Pembaruan 2013-05-10: Implementasi untuk Django 1.5 di GitHub. Perubahan kecil dalam pengalihan di urls.py dan penggunaan tag templat url di list.html. Berkat hubert3 untuk usahanya.
Pembaruan 2013-12-07: Django 1.6 didukung di GitHub. Satu impor berubah di myapp / urls.py. Terima kasih kepada Arthedian .
Pembaruan 2015-03-17: Django 1.7 didukung di GitHub, terima kasih kepada aronysidoro .
Pembaruan 2015-09-04: Django 1.8 didukung di GitHub, terima kasih kepada nerogit .
Pembaruan 2016-07-03: Django 1.9 didukung di GitHub, terima kasih kepada daavve dan nerogit
Proyek Django 1.3 dasar dengan satu aplikasi dan media / direktori untuk diunggah.
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
Untuk mengunggah dan menyajikan file, Anda perlu menentukan di mana Django menyimpan file yang diunggah dan dari URL apa Django menyajikannya. MEDIA_ROOT dan MEDIA_URL secara default di setting.py tetapi kosong. Lihat baris pertama dalam Django Mengelola File untuk detailnya. Ingat juga atur database dan tambahkan myapp ke 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',
)
Selanjutnya Anda memerlukan model dengan FileField. Bidang khusus ini menyimpan file misalnya ke media / dokumen / 2011/12/24 / berdasarkan tanggal saat ini dan MEDIA_ROOT. Lihat referensi FileField .
# -*- coding: utf-8 -*-
from django.db import models
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
Untuk menangani unggahan dengan baik, Anda memerlukan formulir. Formulir ini hanya memiliki satu bidang tetapi itu sudah cukup. Lihat referensi Formulir FileField untuk detailnya.
# -*- coding: utf-8 -*-
from django import forms
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file',
help_text='max. 42 megabytes'
)
Tampilan di mana semua keajaiban terjadi. Perhatikan bagaimana request.FILES
penanganannya. Bagi saya, itu sangat sulit untuk menemukan fakta yang request.FILES['docfile']
dapat disimpan ke model. File hanya seperti itu. Save model () menangani penyimpanan file ke sistem file secara otomatis.
# -*- 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)
)
Django tidak menayangkan MEDIA_ROOT secara default. Itu akan berbahaya di lingkungan produksi. Tetapi dalam tahap pengembangan, kita bisa memotong pendek. Perhatikan baris terakhir. Baris itu memungkinkan Django untuk menyajikan file dari MEDIA_URL. Ini hanya berfungsi pada tahap pengembangan.
Lihat referensi django.conf.urls.static.static untuk detailnya. Lihat juga diskusi ini tentang menyajikan file media .
# -*- 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)
Agar tampilan dapat diakses, Anda harus menentukan url untuk itu. Tidak ada yang istimewa di sini.
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
urlpatterns = patterns('myapp.views',
url(r'^list/$', 'list', name='list'),
)
Bagian terakhir: templat untuk daftar dan formulir unggahan di bawahnya. Formulir harus memiliki atribut enctype-set ke "multipart / form-data" dan metode set ke "posting" untuk memungkinkan unggahan ke Django. Lihat dokumentasi Upload File untuk detailnya.
FileField memiliki banyak atribut yang dapat digunakan dalam templat. Misalnya {{document.docfile.url}} dan {{document.docfile.name}} seperti pada templat. Lihat lebih lanjut tentang ini di Menggunakan file dalam artikel model dan dokumentasi objek 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>
Jalankan saja syncdb dan runserver.
> cd myproject
> python manage.py syncdb
> python manage.py runserver
Akhirnya semuanya siap. Pada lingkungan pengembangan Django default, daftar dokumen yang diunggah dapat dilihat di localhost:8000/list/
. Hari ini file diunggah ke / path / ke / myproject / media / dokumen / 2011/12/17 / dan dapat dibuka dari daftar.
Saya harap jawaban ini akan membantu seseorang sebanyak itu akan membantu saya.
{% url list %}
menjadi {% url "list" %}
.
Secara umum ketika Anda mencoba untuk 'hanya mendapatkan contoh kerja' yang terbaik adalah 'mulai menulis kode'. Tidak ada kode di sini untuk membantu Anda, sehingga membuat menjawab pertanyaan lebih bermanfaat bagi kami.
Jika Anda ingin mengambil file, Anda perlu sesuatu seperti ini di file html di suatu tempat:
<form method="post" enctype="multipart/form-data">
<input type="file" name="myfile" />
<input type="submit" name="submit" value="Upload" />
</form>
Itu akan memberi Anda tombol telusuri, tombol unggah untuk memulai tindakan (kirimkan formulir) dan catat enctype sehingga Django tahu untuk memberi Anda request.FILES
Dalam tampilan di suatu tempat Anda dapat mengakses file
def myview(request):
request.FILES['myfile'] # this is my file
Ada sejumlah besar informasi dalam dokumen unggahan file
Saya sarankan Anda membaca halaman secara menyeluruh dan mulai menulis kode - kemudian kembali dengan contoh dan susun jejak ketika itu tidak berfungsi.
enctype="multipart/form-data"
apa yang saya butuhkan untuk membuat pekerjaan ini, terima kasih!
Lihat repo github , bekerja dengan Django 3
Jalankan startproject ::
$ django-admin.py startproject sample
sekarang folder ( contoh ) dibuat.
Buat aplikasi ::
$ cd sample
$ python manage.py startapp uploader
Sekarang folder ( uploader
) dengan file-file ini dibuat ::
uploader/
__init__.py
admin.py
app.py
models.py
tests.py
views.py
migrations/
__init__.py
Pada sample/settings.py
tambahkan 'uploader'
ke INSTALLED_APPS
dan tambahkan MEDIA_ROOT
dan MEDIA_URL
, yaitu ::
INSTALLED_APPS = [
'uploader',
...<other apps>...
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
di sample/urls.py
tambahkan ::
...<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)
perbarui uploader/models.py
::
from django.db import models
class Upload(models.Model):
upload_file = models.FileField()
upload_date = models.DateTimeField(auto_now_add =True)
perbarui 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
Buat contoh folder / pengunggah / templat / pengunggah
Buat file upload_form.html yaitu 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>
Sinkronkan basis data dan runserver ::
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver
kunjungi http: // localhost: 8000 /
FileField
sementara suhail menggunakan ImageField
, bisakah seseorang tolong menjelaskan pilihannya?
FileField
. ImageField
harus untuk hanya mengunggah gambar. pembaruan akan bekerja dengan Django 1.11.
Saya harus mengatakan saya menemukan dokumentasi di Django membingungkan. Juga untuk contoh paling sederhana mengapa formulir disebutkan? Contoh saya bekerja di views.py adalah: -
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()
File html terlihat seperti kode di bawah ini, meskipun contoh ini hanya mengunggah satu file dan kode untuk menyimpan banyak file: -
<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>
Contoh-contoh ini bukan kode saya, mereka telah memilih dari dua contoh lain yang saya temukan. Saya seorang pemula relatif untuk Django sehingga sangat mungkin saya kehilangan beberapa poin kunci.
FileField
dan a model.Form
. Untuk pemula (dan untuk tugas-tugas sepele), pemrosesan manual dari file yang diunggah seperti yang ditunjukkan di atas kurang membingungkan.
Saya juga punya persyaratan serupa. Sebagian besar contoh di internet meminta untuk membuat model dan membuat formulir yang tidak ingin saya gunakan. Ini kode terakhir saya.
if request.method == 'POST':
file1 = request.FILES['file']
contentOfFile = file1.read()
if file1:
return render(request, 'blogapp/Statistics.html', {'file': file1, 'contentOfFile': contentOfFile})
Dan dalam HTML untuk mengunggah saya menulis:
{% 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 %}
Berikut ini adalah HTML yang menampilkan konten file:
{% block content %}
<h3>File uploaded successfully</h3>
{{file.name}}
</br>content = {{contentOfFile}}
{% endblock %}
Memperluas pada contoh 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
Anda dapat memanggil handle_uploaded_file
fungsi ini dari tampilan Anda dengan objek file yang diunggah. Ini akan menyimpan file dengan nama unik (diawali dengan nama file dari file yang diunggah asli) dalam sistem file dan mengembalikan path lengkap file yang disimpan. Anda dapat menyimpan path dalam database, dan melakukan sesuatu dengan file nanti.
request.FILES['myfile']
) ke handle_uploaded_file
, bukan objeknya request
sendiri.
prefix=source.name
menambahkan karakter tambahan di akhir file, mengacaukan ekstensi file. Misalnya upload.csv
diubah menjadi upload.csv5334
. Mengubahnya untuk suffix=source.name
memperbaikinya untuk saya.
Di sini dapat membantu Anda: membuat bidang file di models.py Anda
Untuk mengunggah file (di admin.py Anda):
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)
dan gunakan bidang itu di templat Anda juga.
Anda dapat merujuk ke contoh server di Pengunggah Baik, yang memiliki versi Django. https://github.com/FineUploader/server-examples/tree/master/python/django-fine-uploader
Ini sangat elegan dan yang paling penting dari semuanya, ia menyediakan fitur js lib. Template tidak termasuk dalam contoh server, tetapi Anda dapat menemukan demo di situs webnya. Pengunggah Baik: http://fineuploader.com/demos.html
views.py
UploadView mengirimkan kiriman dan menghapus permintaan ke masing-masing penangan.
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)
Saya menghadapi masalah yang sama, dan diselesaikan oleh situs 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)