石油王研究課|CIFLAB

CIFLAB石油王研究課の活動ブログです。

Django2.0 ファイルアップロードについて

Django2.0でファイルアップロードの仕方で少しだけ詰まったのでメモしておきます。

まず最初にディレクトリ構成はこんな感じです。

├─.vscode
├─apps
│ ├─media
│ │ └─thumbnail
│ ├─products
│ │ └─migrations
│ ├─static
│ │ └─vendor
│ │ └─bootstrap
│ │ ├─css
│ │ ├─img
│ │ └─js
│ └─templates
│ ├─accounts
│ └─products
├─config
└─docs

今回はmediaの中のthumbnailに画像を保存することを目的としました。

まずmodel.pyから

from django.db import models

class Product(models.Model):
    title = models.CharField(max_length=140)
    thumbnail = models.FileField(upload_to='thumbnail/', blank=True, null=True)
    sentence = models.TextField()

次にform.py

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = ("title","thumbnail","sentence")

views.py

request.FILESというディレク処理の中にファイルのデータが入っているので、フォームへデータを受け渡します。
https://docs.djangoproject.com/ja/2.0/topics/http/file-uploads/

from django.shortcuts import render, redirect

from django.views.generic import CreateView

from .models import Product
from .forms import ProductForm

from django.urls import reverse, reverse_lazy

class ProductCreateView(CreateView):
    template_name = "products/product_create_form.html"
    form_class = ProductForm
    model = Product
    success_url = reverse_lazy('products')

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST, request.FILES)
        if form.is_valid():
            print('VALID')
            form.save()
            return redirect(reverse('products'))
        print('Not valid')
        return redirect(reverse('post'))

そしてフォームのproduct_create_form.htmlですが、enctype="multipart/form-data"を入れ忘れないようにしましょう。
私はこれを入れ忘れてかれこれ3時間くらい格闘する羽目になりました...
mugenup-tech.hatenadiary.com

{% extends "base.html" %}

{%block body%}

    <h1>新規作成</h1>
    <form action="" method="post" enctype="multipart/form-data" data-ajax="false">
        {% csrf_token %}
        <table class="table">
            {{ form }}
        </table>

        <button class="btn btn-primary" type="submit">送信</button>    
    </form>
{% endblock %}

そしてsettings.pyに以下を追加します。

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

これでファイルをアップロードできるようになりました。