Нужен минимальный пример загрузки файла Django [закрыт]

Как новичок в Django, у меня возникли трудности с загрузкой приложения в Django 1.3. Я не смог найти ни одного современного примера / фрагментов. Может ли кто-то опубликовать минимальный, но полный (модель, представление, шаблон) пример кода для этого?

10 ответов


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 в списке.формат 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.py

1. Параметры: 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. Это работает только на стадии разработки.

посмотреть Джанго.conf.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 / шаблоны / myapp / список.HTML-код

последняя часть: шаблон для списка и отправить форму ниже. Форма должна иметь атрибут enctype, установленный в "multipart / form-data", и метод, установленный в" post", чтобы сделать загрузку в Django возможной. См.загрузка документации для сведения.

поле FileField имеет множество атрибутов, которые можно использовать в шаблонах. Е. Г. {{ документ.docfile.url }} и {{ документ.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 и 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

Я рекомендую вам внимательно прочитать страницу и просто начните писать код - затем вернитесь с примерами и трассировками стека, когда он не работает.


демо

обновление Аксели Palén это. вижу GitHub РЕПО, работает с Джанго 2

минимальный пример загрузки файла Django

1. Создайте проект django

выполнить startproject::

$ django-admin.py startproject sample

теперь в папке(пример) составляет:

sample/
  manage.py
  sample/
    __init__.py
    settings.py
    urls.py
    wsgi.py 

2. создать приложение

создать app::

$ 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

On sample/settings.py добавить 'uploader.apps.UploaderConfig' to INSTALLED_APPS и добавить MEDIA_ROOT и MEDIA_URL, ie::

INSTALLED_APPS = [
    ...<other apps>...
    'uploader.apps.UploaderConfig',
]

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

4. Обновление urls.py

на 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. создание шаблонов

создать папку шаблоны в папке пользователя, затем создать файл дома.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. Syncronize database

синхронизировать базу данных и 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>

эти примеры не мой код, они были optained из двух примеров, которые я нашел. Я относительный новичок в 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 функция из вашего представления с загруженным объектом file. Это сохранит файл с уникальным именем (с префиксом filename исходного загруженного файла) в файловой системе и вернет полный путь сохраненного файла. Вы можете сохранить путь в базе данных, и сделать что-то с файлом позже.


у меня также было аналогичное требование. Большинство примеров в сети просят создавать модели и создавать формы, которые я не хотел использовать. Вот мой последний код.

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. Шаблон не входит в сервер-примеры, но вы можете найти демо на своем сайте. Fine Uploader: http://fineuploader.com/demos.html

django-fine-загрузчик

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.

# 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)