1. ホーム
  2. django

[解決済み] Djangoでファイルをアップロードする方法は?[クローズド]。

2022-03-14 18:41:59

質問

Django の初心者である私は、Django 1.3 でアップロードアプリを作るのに苦労しています。最新のサンプル/スニペットを見つけることができませんでした。どなたか、最小限の、しかし完全な (モデル、ビュー、テンプレート) サンプルコードを投稿していただけませんか?

どのように解決するのですか?

ふぅ、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 更新。 Django 1.5用の実装をGitHubで公開。urls.py のリダイレクトと list.html の url テンプレートタグの使い方を少し変更しました。感謝 ヒューバート3 を作成しました。

2013-12-07に更新しました。 GitHubでDjango1.6に対応しました。myapp/urls.py の import を一つ変更しました。以下の方に感謝します。 アーテジアン .

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 がアップロードされたファイルをどこに保存し、どの URL から Django がファイルを配信するかを指定する必要があります。MEDIA_ROOT と MEDIA_URL はデフォルトで settings.py にありますが、空になっています。の最初の行を見てください。 Djangoのファイル管理 をご覧ください。データベースを設定し、INSTALLED_APPSにmyappを追加することも忘れないでください。

...
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

アップロードをうまく処理するためには、フォームが必要です。このフォームにはフィールドが一つしかありませんが、それで十分です。以下のようになります。 フォーム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'] は、そのままmodels.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 リファレンス をご覧ください。以下もご参照ください。 メディアファイルの配信に関するこの議論 .

# -*- 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" に、method を "post" に設定しなければなりません。以下を参照してください。 ファイルアップロードのドキュメント をご覧ください。

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とrunserverを実行するだけです。

> cd myproject
> python manage.py syncdb
> python manage.py runserver

成果

最後に、すべての準備が整いました。デフォルトの Django 開発環境では、アップロードされたドキュメントの一覧は次の場所で見ることができます。 localhost:8000/list/ . 今日、ファイルは /path/to/myproject/media/documents/2011/12/17/ にアップロードされ、リストから開くことができるようになりました。

この回答が、私が助けられたのと同じように、誰かの助けになることを願っています。