Django でファイルをアップロード

ほぼ次のページを参考にしました。
[ファイルのアップロード](https://docs.djangoproject.com/ja/2.1/topics/http/file-uploads/)

proj01 というプロジェクトに file_upload というアプリを作成します。

1) file_upload というアプリの作成

```bash
python manage.py startapp file_upload
```

2) proj01/settings.py の編集

```py:proj01/settings.py
（省略）
INSTALLED_APPS = [
    'file_upload',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
（省略）
```

3) proj01/urls.py の編集

```py:proj01/urls.py
from django.contrib import admin
from django.urls import path
from django.urls import include
import file_upload.views as file_upload


urlpatterns = [
    path('success/url/',file_upload.success),
    path('file_upload/',include('file_upload.urls')),
    path('admin/', admin.site.urls),
]
```

4) テンプレートの作成

```bash
mkdir file_upload/templates
mkdir file_upload/templates/file_upload
```

```html:file_upload/templates/file_upload/upload.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<title>ファイルアップロード</title>
</head>
<body>
    <h1>ファイルをアップロード</h1>
    <form method="POST" enctype="multipart/form-data">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">アップロード</button>
    </form>
<hr />
Dec/26/2018<p />
</body>
</html>
```

5) file_upload/forms.py の作成

```py:file_upload/forms.py
from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()
```

6) file_upload/views.py の編集

```py:file_upload/views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
from django.http import HttpResponse

import sys

# ------------------------------------------------------------------
def file_upload(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            sys.stderr.write("*** file_upload *** aaa ***\n")
            handle_uploaded_file(request.FILES['file'])
            file_obj = request.FILES['file']
            sys.stderr.write(file_obj.name + "\n")
            return HttpResponseRedirect('/success/url/')
    else:
        form = UploadFileForm()
    return render(request, 'file_upload/upload.html', {'form': form})
#
#
# ------------------------------------------------------------------
def handle_uploaded_file(file_obj):
    sys.stderr.write("*** handle_uploaded_file *** aaa ***\n")
    sys.stderr.write(file_obj.name + "\n")
    file_path = 'media/documents/' + file_obj.name 
    sys.stderr.write(file_path + "\n")
    with open(file_path, 'wb+') as destination:
        for chunk in file_obj.chunks():
            sys.stderr.write("*** handle_uploaded_file *** ccc ***\n")
            destination.write(chunk)
            sys.stderr.write("*** handle_uploaded_file *** eee ***\n")
#
# ------------------------------------------------------------------
def success(request):
    str_out = "Success!<p />"
    str_out += "成功<p />"
    return HttpResponse(str_out)
# ------------------------------------------------------------------
```

7) file_upload/urls.py の作成

```py:file_upload/urls.py
from django.urls import path

from . import views

urlpatterns = [
    path('', views.file_upload, name='file_upload'),
]
```

8) ファイルをアップロードするフォルダーを作成

```bash
mkdir media
mkdir media/documents
```

8) マイグレーション

```bash
python manage.py migrate
```

9) 開発サーバーを起動

```bash
python manage.py runserver
```

9) ブラウザーで http://127.0.0.1:8000/file_upload/ にアクセスします。

![upload_dec2601.png](https://qiita-image-store.s3.amazonaws.com/0/179446/79c004ff-be1f-5900-e861-d37463657b7f.png)


ファイルを選択してアップロードすると、media/documents/ にアップロードされます。

![upload_dec2701.png](https://qiita-image-store.s3.amazonaws.com/0/179446/d04e4900-98c9-c058-0c92-a1233222c360.png)

コードは GitHub にあります。
[ekzemplaro/django_file_upload](https://github.com/ekzemplaro/django_file_upload)


次のバージョンで確認しました。

```text
$ python --version
Python 3.7.3
$ python -m django --version
3.2.9
```