Как новичок в Django, мне сложно создать приложение для загрузки в Django 1.3. Я не смог найти свежий пример/фрагменты. Может кто-нибудь отправить минимальный, но полный (модель, вид, шаблон) пример кода для этого?
Нужен минимальный пример загрузки файла Django
Ответ 1
У Phew, документации Django действительно нет хорошего примера об этом. Я потратил более 2 часов, чтобы выкопать все части, чтобы понять, как это работает. Благодаря этим знаниям я реализовал проект, который позволяет загружать файлы и показывать их как список. Чтобы загрузить исходный код для проекта, посетите https://github.com/axelpale/minimal-django-file-upload-example или выполните клонирование:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git
Обновление 2013-01-30: У источника в GitHub также есть реализация для Django 1.4 в дополнение к 1.3. Несмотря на небольшое количество изменений, следующий учебник также полезен для версии 1.4.
Обновление 2013-05-10: Реализация Django 1.5 в GitHub. Незначительные изменения в перенаправлении в urls.py и использование тега шаблона url в list.html. Благодаря hubert3 для усилий.
Обновление 2013-12-07: Django 1.6 поддерживается в GitHub. Один импорт изменился в myapp/urls.py. Спасибо, Arthedian.
Обновление 2015-03-17: Django 1.7 поддерживается в GitHub, благодаря aronysidoro.
Обновление 2015-09-04: Django 1.8 поддерживается в GitHub благодаря nerogit. p >
Обновление 2016-07-03: Django 1.9 поддерживается в GitHub благодаря daavve и nerogit
Дерево проектов
Основной проект Django 1.3 с одним приложением и медиа/каталогом для загрузки.
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. Настройки: myproject/settings.py
Чтобы загружать и обслуживать файлы, вам нужно указать, где Django хранит загруженные файлы и из какого URL-адреса Django их обслуживает. MEDIA_ROOT и MEDIA_URL находятся в settings.py по умолчанию, но они пусты. Подробнее см. В первых строках в Django Управление файлами. Запомните также установить базу данных и добавить 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. Модель: myproject/myapp/models.py
Затем вам понадобится модель с файловым полем. В этом конкретном поле хранятся файлы, например. на средства массовой информации/документы/2011/12/24/на основе текущей даты и MEDIA_ROOT. См. Ссылка на FileField.
# -*- coding: utf-8 -*-
from django.db import models
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
3. Форма: myproject/myapp/forms.py
Для удобной обработки загрузки вам нужна форма. Эта форма имеет только одно поле, но этого достаточно. Подробнее см. Ссылка на файл FileField.
# -*- coding: utf-8 -*-
from django import forms
class DocumentForm(forms.Form):
docfile = forms.FileField(
label='Select a file',
help_text='max. 42 megabytes'
)
4. Вид: myproject/myapp/views.py
Вид, где происходит вся магия. Обратите внимание, как обрабатываются request.FILES
. Для меня было очень трудно заметить, что request.FILES['docfile']
можно сохранить в моделях. FileField просто так. Модель save() автоматически сохраняет файл в файловой системе.
# -*- 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 проекта: myproject/urls.py
Django по умолчанию не поддерживает MEDIA_ROOT. Это было бы опасно в производственной среде. Но на стадии разработки мы могли прерваться. Обратите внимание на последнюю строку. Эта строка позволяет Django обслуживать файлы из MEDIA_URL. Это работает только на стадии разработки.
Подробнее см. django.conf.urls.static.static reference. См. Также эту дискуссию о обслуживании мультимедийных файлов.
# -*- 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-адреса приложений: myproject/myapp/urls.py
Чтобы сделать представление доступным, вы должны указать URL-адреса для него. Здесь ничего особенного.
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
urlpatterns = patterns('myapp.views',
url(r'^list/$', 'list', name='list'),
)
7. Шаблон: myproject/myapp/templates/myapp/list.html
Последняя часть: шаблон для списка и форма для загрузки под ним. У формы должен быть атрибут enctype-атрибут "multipart/form-data" и метод, установленный на "post", чтобы сделать загрузку в Django возможной. Подробнее см. Загрузка файлов.
В FileField есть много атрибутов, которые можно использовать в шаблонах. Например. {{document.docfile.url}} и {{document.docfile.name}}, как в шаблоне. Подробнее об этом см. В Использование файлов в статье моделей и Документация файла 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. Инициализировать
Просто запустите syncdb и runningerver.
> cd myproject
> python manage.py syncdb
> python manage.py runserver
Результаты
Наконец, все готово. В среде разработки Django по умолчанию список загруженных документов можно увидеть на localhost:8000/list/
. Сегодня файлы загружаются в/path/to/myproject/media/documents/2011/12/17/и могут быть открыты из списка.
Я надеюсь, что этот ответ поможет кому-то так же, как и мне.
Ответ 2
Вообще говоря, когда вы пытаетесь "просто получить рабочий пример", лучше всего "начать писать код". Здесь нет кода, чтобы помочь вам, поэтому он дает ответ на этот вопрос намного больше для нас.
Если вы хотите захватить файл, вам нужно что-то подобное в файле html где-то:
<form method="post" enctype="multipart/form-data">
<input type="file" name="myfile" />
<input type="submit" name="submit" value="Upload" />
</form>
Это даст вам кнопку обзора, кнопку загрузки, чтобы начать действие (отправьте форму), и обратите внимание на enctype, чтобы Django знал, чтобы дать вам request.FILES
В представлении где-нибудь вы можете получить доступ к файлу с помощью
def myview(request):
request.FILES['myfile'] # this is my file
В файлах загрузки файлов имеется огромное количество информации.
Я рекомендую вам внимательно прочитать страницу и просто начать писать код, а затем вернуться с примерами и трассировкой стека, когда это не сработает.
Ответ 3
демонстрация
Обновление ответа Аксели Палена. см. репозиторий github, работает с Django 2
Минимальный пример загрузки файла Django
1. Создайте проект django
Запустить startproject ::
$ django-admin.py startproject sample
теперь создается папка (образец) ::
sample/
manage.py
sample/
__init__.py
settings.py
urls.py
wsgi.py
2. создать приложение
Создать приложение ::
$ cd sample
$ python manage.py startapp uploader
Теперь создается папка (uploader
) с этими файлами ::
uploader/
__init__.py
admin.py
app.py
models.py
tests.py
views.py
migrations/
__init__.py
3. Обновить settings.py
На sample/settings.py
добавьте 'uploader.apps.UploaderConfig'
в INSTALLED_APPS
и добавьте MEDIA_ROOT
и MEDIA_URL
, то есть ::
INSTALLED_APPS = [
...<other apps>...
'uploader.apps.UploaderConfig',
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
4. Обновите urls.py
в sample/urls.py
add ::
...<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. Обновите models.py
обновить 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. Обновите view.py
обновить 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. Создание шаблонов
Создайте шаблоны папок в папке uploader, затем создайте файл home.html, то есть 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. Синхронизировать базу данных
Синхронизировать базу данных и серверы запуска ::
$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver
посетите http://localhost.com:8000
Ответ 4
Я должен сказать, что я нашел документацию в django запутанной. Также для простейшего примера, почему упоминаются формы? Пример, который я получил для работы в представлении views.py: -
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 выглядит как код ниже, хотя в этом примере загружается только один файл, а код для сохранения файлов обрабатывает многие: -
<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>
Эти примеры не являются моим кодом, они были получены из двух других примеров, которые я нашел. Я относительный новичок в django, поэтому, скорее всего, мне не хватает ключевого момента.
Ответ 5
Продолжение на примере Генри:
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
из вашего представления с загруженным файловым объектом. Это сохранит файл с уникальным именем (с префиксом имени файла исходного загруженного файла) в файловой системе и вернет полный путь к сохраненному файлу. Вы можете сохранить путь в базе данных и сделать что-то с файлом позже.
Ответ 6
Здесь это может помочь вам: создайте поле file.py
Для загрузки файла (в вашем 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)
и также используйте это поле в своем шаблоне.
Ответ 7
У меня также было подобное требование. Большинство примеров в сети просят создать модели и создать формы, которые я не хотел использовать. Вот мой окончательный код.
if request.method == 'POST':
file1 = request.FILES['file']
contentOfFile = file1.read()
if file1:
return render(request, 'blogapp/Statistics.html', {'file': file1, 'contentOfFile': contentOfFile})
И в HTML для загрузки я написал:
{% 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 %}
Ниже приведен HTML, который отображает содержимое файла:
{% block content %}
<h3>File uploaded successfully</h3>
{{file.name}}
</br>content = {{contentOfFile}}
{% endblock %}
Ответ 8
Вы можете обратиться к примерам сервера в Fine Uploader, который имеет версию django. https://github.com/FineUploader/server-examples/tree/master/python/django-fine-uploader
Он очень изящный и, самое главное, содержит признанный js lib. Шаблон не включен в примеры серверов, но вы можете найти демо на своем веб-сайте. Fine Uploader: http://fineuploader.com/demos.html
Джанго-тонкий загрузчик
views.py
UploadView отправляет сообщения и удаляет запросы соответствующим обработчикам.
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 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
Не уверен, есть ли какие-либо недостатки этого подхода, но еще более минимальные, в views.py:
entry = form.save()
# save uploaded file
if request.FILES['myfile']:
entry.myfile.save(request.FILES['myfile']._name, request.FILES['myfile'], True)
Ответ 10
Я столкнулся с подобной проблемой и решил сайт администратора 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)