Yanıtlar:
Vay be, Django belgelerinde bu konuda gerçekten iyi bir örnek yok. Bunun nasıl çalıştığını anlamak için tüm parçaları kazmak için 2 saatten fazla harcadım. Bu bilgi ile dosyaları yüklemeyi ve liste halinde göstermeyi mümkün kılan bir proje uyguladım. Proje kaynağını indirmek için https://github.com/axelpale/minimal-django-file-upload-example adresini ziyaret edin veya kopyalayın:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git
2013-01-30 Güncellemesi: GitHub'daki kaynak 1.3'e ek olarak Django 1.4 için de uygulandı. Birkaç değişiklik olmasına rağmen, aşağıdaki öğretici 1.4 için de yararlıdır.
2013-05-10 Güncellemesi: GitHub'da Django 1.5 uygulaması. Urls.py dosyasında yeniden yönlendirmede küçük değişiklikler ve list.html dosyasında url şablon etiketinin kullanımı. Bu çaba için hubert3'e teşekkürler .
Güncelleme 2013-12-07: GitHub'da Django 1.6 destekleniyor. Bir içe aktarma işlemi myapp / urls.py olarak değiştirildi. Arthedian'a teşekkürler .
2015-03-17 Güncellemesi: Drongo 1.7, aronysidoro sayesinde GitHub'da desteklendi .
2015-09-04 Güncellemesi: Nerogit sayesinde Django 1.8 GitHub'da desteklendi .
Güncelleme 2016-07-03: Daavve ve Nerogit sayesinde GitHub'da Django 1.9 destekleniyor
Yüklemeler için tek bir uygulama ve medya / dizin ile temel bir Django 1.3 projesi.
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
Dosyaları yüklemek ve sunmak için, Django'nun yüklenen dosyaları nerede depoladığını ve Django'nun hangi URL'den sunduğunu belirtmeniz gerekir. MEDIA_ROOT ve MEDIA_URL varsayılan olarak settings.py'de bulunur, ancak boştur. Ayrıntılar için Django Dosyaları Yönetme'deki ilk satırlara bakın. Veritabanını ayarlamayı ve INSTALLED_APPS'e myapp eklemeyi de unutmayın
...
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',
)
Sonra FileField ile bir modele ihtiyacınız var. Bu özel alan, dosyaları geçerli tarihe ve MEDIA_ROOT'a göre medya / belgeler / 2011/12/24 / şeklinde depolar. Bkz. FileField başvurusu .
# -*- coding: utf-8 -*-
from django.db import models
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
Yüklemeyi iyi işlemek için bir forma ihtiyacınız var. Bu formun sadece bir alanı vardır, ancak bu yeterlidir. Ayrıntılar için Form FileField başvurusuna bakın.
# -*- coding: utf-8 -*-
from django import forms
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file',
help_text='max. 42 megabytes'
)
Tüm büyünün gerçekleştiği bir görünüm. Nasıl request.FILES
ele alındığına dikkat edin . Benim için, request.FILES['docfile']
modellere kaydedilebilecek gerçeği tespit etmek gerçekten zordu . FileField aynen böyle. Modelin save () yöntemi, dosyanın dosya sistemine otomatik olarak depolanmasını sağlar.
# -*- 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 varsayılan olarak MEDIA_ROOT hizmetini sunmaz. Bu üretim ortamında tehlikeli olabilir. Ancak geliştirme aşamasında, kısa kesebiliriz. Son satıra dikkat edin. Bu satır, Django'nun MEDIA_URL dosyalarından dosya sunmasını sağlar. Bu sadece geliştirme aşamasında çalışır.
Ayrıntılar için django.conf.urls.static.static referansına bakın. Medya dosyalarının sunulmasıyla ilgili bu tartışmaya da bakın .
# -*- 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)
Görünümü erişilebilir hale getirmek için görünümün URL'lerini belirtmeniz gerekir. Burada özel bir şey yok.
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
urlpatterns = patterns('myapp.views',
url(r'^list/$', 'list', name='list'),
)
Son bölüm: liste şablonu ve altındaki yükleme formu. Django'ya yüklenmeyi mümkün kılmak için, formun "multipart / form-data" olarak ayarlanmış enctype-özniteliği ve "post" olarak ayarlanmış yöntemi olmalıdır. Ayrıntılar için Dosya Yüklemeleri dokümanına bakın.
FileField, şablonlarda kullanılabilecek birçok özelliğe sahiptir. Şablondaki gibi {{document.docfile.url}} ve {{document.docfile.name}}. Bunlarla ilgili daha fazla bilgiyi Modellerde dosya kullanma makalesi ve Dosya nesnesi belgeleri bölümüne bakın .
<!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>
Sadece syncdb ve runserver'ı çalıştırın.
> cd myproject
> python manage.py syncdb
> python manage.py runserver
Sonunda her şey hazır. Varsayılan olarak Django geliştirme ortamında yüklenen belgelerin listesi adresinde görülebilir localhost:8000/list/
. Bugün dosyalar / path / dizinine / projem / medya / belgeler / 2011/12/17 / dizinine yüklenir ve listeden açılabilir.
Umarım bu cevap birisinin bana yardım ettiği kadar yardımcı olacaktır.
{% url list %}
olur {% url "list" %}
.
Genel olarak, 'sadece çalışan bir örnek almaya' çalışırken, 'sadece kod yazmaya başlamak' en iyisidir. Burada size yardımcı olacak bir kod yok, bu yüzden soruyu cevaplamak bizim için çok daha işe yarar.
Bir dosyayı almak istiyorsanız, bir yerde bir html dosyasında böyle bir şeye ihtiyacınız vardır:
<form method="post" enctype="multipart/form-data">
<input type="file" name="myfile" />
<input type="submit" name="submit" value="Upload" />
</form>
Bu size göz at düğmesi, eylemi başlatmak için bir yükleme düğmesi (formu gönderin) ve Django'nun size vermeyi bilmesi için şifreyi not eder. request.FILES
Bir yerde bir görünümde dosyaya
def myview(request):
request.FILES['myfile'] # this is my file
Dosya yükleme belgelerinde çok miktarda bilgi var
Sayfayı iyice okumanızı ve sadece kod yazmaya başlamanızı öneririm - sonra çalışmazken örnekler ve yığın izleri ile geri dönün.
enctype="multipart/form-data"
Ben, bu işi yapmak için teşekkür gerekeni!
Github deposunu görün, Django 3 ile çalışır
Startproject'i çalıştırın ::
$ django-admin.py startproject sample
şimdi bir klasör ( örnek ) oluşturulur.
Bir uygulama oluşturun ::
$ cd sample
$ python manage.py startapp uploader
Şimdi uploader
bu dosyaları içeren bir klasör ( ) oluşturulur ::
uploader/
__init__.py
admin.py
app.py
models.py
tests.py
views.py
migrations/
__init__.py
On sample/settings.py
eklenti 'uploader'
için INSTALLED_APPS
ve eklemek MEDIA_ROOT
ve MEDIA_URL
, yani ::
INSTALLED_APPS = [
'uploader',
...<other apps>...
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
içinde sample/urls.py
eklenti ::
...<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)
güncelleme uploader/models.py
::
from django.db import models
class Upload(models.Model):
upload_file = models.FileField()
upload_date = models.DateTimeField(auto_now_add =True)
güncelleme 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
Bir klasör örneği / yükleyici / şablonlar / yükleyici oluşturma
Upload_form.html dosyası oluşturun 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>
Veritabanını ve runserver'ı senkronize et ::
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver
ziyaret http: // localhost: 8000 /
FileField
süre suhail kullandı ImageField
, birisi seçenekleri açıklayabilir mi?
FileField
. ImageField
yalnızca resim yüklemek için gerekir. güncelleme Django 1.11 ile çalışacaktır.
Django'da kafa karıştırıcı belgeleri bulduğumu söylemeliyim. Ayrıca en basit örnek için formlardan neden bahsediliyor? Ben views.py çalışmak zorunda örnek: -
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()
Html dosyası aşağıdaki koda benziyor, ancak bu örnek yalnızca bir dosya yükler ve dosyaları kaydetmek için kod çok işlenir: -
<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>
Bu örnekler benim kodum değil, bulduğum diğer iki örnekten elde edildi. Ben django göreceli bir acemiyim, bu yüzden bazı önemli noktaları kaçırıyorum.
FileField
ve a kullanmadığınız için +1 model.Form
. Yeni başlayanlar (ve önemsiz görevler için), yukarıda gösterildiği gibi yüklenen dosyaların manuel olarak işlenmesi daha az kafa karıştırıcıdır.
Ben de benzer bir gereksinimim vardı. Net'teki örneklerin çoğu, kullanmak istemediğim modeller ve formlar oluşturmayı istiyor. İşte son kodum.
if request.method == 'POST':
file1 = request.FILES['file']
contentOfFile = file1.read()
if file1:
return render(request, 'blogapp/Statistics.html', {'file': file1, 'contentOfFile': contentOfFile})
Ve yüklemek için HTML'de yazdım:
{% 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 %}
Dosyanın içeriğini gösteren HTML aşağıdadır:
{% block content %}
<h3>File uploaded successfully</h3>
{{file.name}}
</br>content = {{contentOfFile}}
{% endblock %}
Henry örneğini genişletmek :
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
handle_uploaded_file
Yüklenen dosya nesnesiyle görünümünüzden bu işlevi çağırabilirsiniz . Bu, dosyayı benzersiz bir adla (yüklenen orijinal dosyanın dosya adıyla ön ekli) dosya sistemine kaydeder ve kaydedilen dosyanın tam yolunu döndürür. Yolu veritabanına kaydedebilir ve daha sonra dosyayla bir şeyler yapabilirsiniz.
request.FILES['myfile']
) kendisine handle_uploaded_file
değil, request
iletin.
prefix=source.name
dosya sonuna ekstra karakterler ekleyerek dosya uzantısıyla uğraşmak. Örneğin upload.csv
değiştirildi var upload.csv5334
. Bunu benim için suffix=source.name
düzeltmek için değiştirmek .
Burada size yardımcı olabilir: models.py'nizde bir dosya alanı oluşturun
Dosyayı yüklemek için (admin.py dosyasında):
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)
ve bu alanı şablonunuzda da kullanabilirsiniz.
Django sürümü olan Fine Uploader'daki sunucu örneklerine başvurabilirsiniz. https://github.com/FineUploader/server-examples/tree/master/python/django-fine-uploader
Çok zarif ve en önemlisi, özellikli js lib sağlar. Şablon sunucu örneklerine dahil edilmemiştir, ancak web sitesinde demo bulabilirsiniz. İnce Yükleyici: http://fineuploader.com/demos.html
views.py
UploadView ilgili işleyicilere gönderi ve silme isteği gönderir.
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)
Benzer bir sorunla karşılaştım ve django yönetici sitesi tarafından çözüldüm.
# 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)