Django でファイルをアップロードするにはどうすればいいですか? [closed] 質問する

Django でファイルをアップロードするにはどうすればいいですか? [closed] 質問する

Django 1.3 を使用してユーザーがファイルをアップロードできるようにする「hello world」アプリに必要な最小限のサンプル コードは何ですか?

ベストアンサー1

ああ、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 のソースには、1.3 に加えて Django 1.4 の実装もあります。変更点はほとんどありませんが、次のチュートリアルは 1.4 にも役立ちます。

2013-05-10 更新: GitHub の Django 1.5 の実装。urls.py のリダイレクトと list.html の url テンプレート タグの使用法に若干の変更が加えられました。ヒューバート3ご尽力に感謝いたします。

2013-12-07更新: GitHubでDjango 1.6がサポートされました。myapp/urls.pyのインポートを1つ変更しました。アルセディアン

2015-03-17更新: Django 1.7がGitHubでサポートされました。アロニシドロ

2015-09-04更新: Django 1.8がGitHubでサポートされました。ネロギット

2016-07-03更新: Django 1.9がGitHubでサポートされました。ダウヴェそしてネロギット

プロジェクトツリー

アップロード用の単一のアプリと media/ ディレクトリを備えた基本的な 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がアップロードしたファイルを保存する場所と、Djangoがそれらを提供するURLを指定する必要があります。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

次に、FileField を持つモデルが必要です。この特定のフィールドは、現在の日付と MEDIA_ROOT に基づいて、たとえば media/documents/2011/12/24/ にファイルを保存します。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

アップロードをうまく処理するには、フォームが必要です。このフォームにはフィールドが1つしかありませんが、それで十分です。フォームファイルフィールド参照詳細については。

# -*- 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処理されるかに注意してください。私にとっては、models.FileField にそのまま保存できるという事実を見つけるのは本当に困難でしたrequest.FILES['docfile']。モデルの 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 リファレンス詳細については、メディアファイルの提供に関する議論

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

最後の部分: リストのテンプレートとその下のアップロードフォーム。Django へのアップロードを可能にするには、フォームの enctype-attribute を "multipart/form-data" に設定し、メソッドを "post" に設定する必要があります。ファイルアップロードのドキュメント詳細については。

FileField にはテンプレートで使用できる属性が多数あります。たとえば、テンプレート内の {{ document.docfile.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/ にアップロードされ、リストから開くことができます。

この回答が私にとって役立ったのと同じくらい、誰かの役に立つことを願っています。

おすすめ記事