Нужен минимальный пример загрузки файла Django [закрыт]
Как новичок в Django, у меня возникли трудности с загрузкой приложения в Django 1.3. Я не смог найти ни одного современного примера / фрагментов. Может ли кто-нибудь опубликовать минимальный, но полный (модель, представление, шаблон) пример кода для этого?
10 ответов:
УФ, документация Django действительно не имеет хорошего примера об этом. Я потратил более 2 часов, чтобы выкопать все части, чтобы понять, как это работает. С этими знаниями я реализовал проект, который позволяет загружать файлы и показывать их в виде списка. Чтобы загрузить исходный код для проекта, посетитеhttps://github.com/axelpale/minimal-django-file-upload-example или клонировать его:
> git clone https://github.com/axelpale/minimal-django-file-upload-example.git2013-01-30 обновления: источник в GitHub также имеет реализации для Django 1.4 В дополнение к 1.3. Хотя есть несколько изменений следующий учебник также полезен для 1.4.
2013-05-10 обновления: реализация для Django 1.5 на GitHub. Незначительные изменения в перенаправлении в urls.py и использование тега шаблона url в списке.формат 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.
обновление 2016-07-03: Django 1.9 поддерживается на GitHub, благодаря daavve и nerogit
дерево проекта
A базовый проект 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.py1. Параметры: myproject/settings.py
чтобы загружать и обслуживать файлы, вам нужно указать, где Django хранит загруженные файлы и с какого URL Django их обслуживает. MEDIA_ROOT и MEDIA_URL находятся в settings.py по умолчанию, но они пусты. Смотрите первые строки в Django Управление Файлами для сведения. Помните также установить базу данных и добавить приложение в 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
Далее вам нужна модель с FileField. В этом конкретном поле хранятся файлы, например, для мультимедиа / документов/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. Это работает только на стадии разработки.
посмотреть Джанго.конф.URL-адреса.статический.статическая ссылка для сведения. Смотрите также эта дискуссия о обслуживании медиа-файлов.
# -*- 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 имеет множество атрибутов, которые можно использовать в шаблонах. Например, {{ документ.документа.url }} и {{ document.docfile.name }} как в шаблоне. Смотрите больше об этом в использование файлов в модели статьи и документация по объекту файла.
<!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 и runserver.
> cd myproject > python manage.py syncdb > python manage.py runserverрезультаты
наконец, все готово. В среде разработки Django по умолчанию список загруженных документов можно посмотреть по адресу
localhost:8000/list/. Сегодня файлы загружаются в /path/to/myproject / media / documents/2011/12/17/ и может быть открыт из списка.Я надеюсь, что этот ответ поможет кому-то так же, как это помогло бы мне.
вообще говоря, когда вы пытаетесь просто получить рабочий пример' лучше 'просто начать писать код. Здесь нет кода, чтобы помочь вам, поэтому он делает ответ на вопрос намного больше работы для нас.
Если вы хотите захватить файл, вам нужно что-то вроде этого в 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существует огромное количество информации в загрузка файлов docs
Я рекомендую вам внимательно прочитать страницу и просто начните писать код - тогда возвращайтесь с примерами и трассировки стека, когда он не работает.
демо
обновление ответ Аксели Палена. смотрите GitHub РЕПО, работает с Django 2
минимальный пример загрузки файла Django
1. Создайте проект django
выполнить startproject::
$ django-admin.py startproject sampleтеперь в папке(пример) составляет:
sample/ manage.py sample/ __init__.py settings.py urls.py wsgi.py2. создать приложение
создать приложение::
$ cd sample $ python manage.py startapp uploaderтеперь в папке(
uploader) С помощью этих файлов создаются::uploader/ __init__.py admin.py app.py models.py tests.py views.py migrations/ __init__.py3. Обновление settings.py
On
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
in
sample/urls.pyдобавить::...<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. Обновление views.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, затем создать файл дома.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. Синхронизировать базу данных
синхронизация базы данных и runserver::
$ python manage.py makemigrations $ python manage.py migrate $ python manage.py runserverпосетите http://localhost.com:8000
Я должен сказать, что нахожу документацию в 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, так что это очень вероятно, я упускаю какой-то ключевой момент.
площадью Генри:
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функция из вашего представления с загруженным файловым объектом. Это позволит сохранить файл с уникальным именем (с префиксом имени файла исходного загруженного файла) в файловой системе и вернуть полный путь к сохраненному файлу. Вы можете сохранить путь в базе данных, и сделать что-то с файлом позже.
у меня также было аналогичное требование. Большинство примеров в сети просят создавать модели и создавать формы, которые я не хотел использовать. Вот мой окончательный код.
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 %}
здесь это может помочь вам: создайте поле файла в вашем models.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)и использовать это поле в ваш шаблон.
вы можете обратиться к примерам сервера в Fine Uploader, который имеет версию django. https://github.com/FineUploader/server-examples/tree/master/python/django-fine-uploader
это очень элегантный и самый важный из всех, он обеспечивает признакам JS lib. Шаблон не входит в сервер-примеры, но вы можете найти демо на своем сайте. Прекрасный Загрузчик: http://fineuploader.com/demos.html
django-fine-uploader
views.py
UploadView отправляет запрос post и delete соответствующим обработчикам.
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)
Не уверен, есть ли какие-либо недостатки в этом подходе, но даже более минимальные, в views.py:
entry = form.save() # save uploaded file if request.FILES['myfile']: entry.myfile.save(request.FILES['myfile']._name, request.FILES['myfile'], True)
я столкнулся с аналогичной проблемой, и решил 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)
Comments