質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2578閲覧

<python,django>送信フォームからの画像のアップロード時にエラーが出てしまう

sr2460

総合スコア50

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/01/25 03:35

前提・実現したいこと

前回このような形でListViewとCreateViewを1つのページで表示させられるようにしました。

リンク内容

今度はCreateViewに画像アップロード機能を加えるべくmodels.pyに以下のコードを加え各種設定をいたしました。

python

1file = models.FileField('ファイル', blank=True, null=True)

発生している問題・エラーメッセージ

しかし投稿フォームの送信ボタンを押すと画像のようにエラーが出てしまいます。

イメージ説明

該当のソースコード

urls.py

python

1 2from django.urls import path 3 4from . import views 5 6app_name = 'board' 7urlpatterns = [ 8 path('', views.FormAndListView.as_view(), name='board'), 9] 10 11

models.py

python

1 2from django.db import models 3from django.utils import timezone 4 5class Post(models.Model): 6 class Meta: 7 verbose_name = '投稿' 8 verbose_name_plural = '投稿リスト' 9 10 name = models.CharField('名前', max_length=20) 11 text = models.TextField('本文') 12 date = models.DateTimeField('日付', default=timezone.now) 13 file = models.FileField('ファイル', blank=True, null=True) 14 15 16 def __str__(self): 17 return self.text 18 19

forms.py

#!/usr/bin/env python # -*- coding: utf-8 -*- from django import forms from django.views import generic from .models import Post class PostForm(forms.ModelForm): #fileアップロード部分のラベルを消去 file = forms.FileField( label='' ) class Meta: model = Post fields = ('name', 'text', 'file')

views.py

#!/usr/bin/env python # -*- coding: utf-8 -*- from .models import Post from django.urls import reverse_lazy from django.shortcuts import render from .forms import PostForm from django.views import generic #from django.views.generic.base import TemplateResponseMixin class FormView(generic.CreateView): model = Post form_class = PostForm template_name = 'board/board.html' success_url = reverse_lazy('board:board') class ListView(generic.ListView): model = Post def get_queryset(self): return Post.objects.order_by('-date') class FormAndListView(FormView, ListView):#, TemplateResponseMixin) def get(self, request, *args, **kwargs): formset = PostForm(request.POST or None, files=request.FILES or None) formView = FormView.get(self, request, *args, **kwargs) listView = ListView.get(self, request, *args, **kwargs) formData = formView.context_data['form'] listData = listView.context_data['object_list'] context = {'form' : formData, 'post_list' : listData} return render(request, 'board/board.html', context)

board.html

<form action="" method="POST"> {{ form.as_p }} <button type="submit">送信</button> {% csrf_token %} </form> {% for post in post_list %} <p>{{ post.name }}</p> <p>{{ post.text | linebreaksbr }}</p> {% if post.file %} <p><img src="{{ post.file.url }}" ></p> {% endif %} <p>{{ post.date }}</p> {% endfor %}

管理画面からは画像を送信でき、なおかつboard.htmlに一覧表示されるためhtmlに問題はないと思っています。

試したこと①

views.pyにTemplateResponseMixinをいれてみました

python

1 2from django.views.generic.base import TemplateResponseMixin 3 4 5class FormAndListView(FormView, ListView, TemplateResponseMixin): 6 def get(self, request, *args, **kwargs): 7 formset = PostForm(request.POST or None, files=request.FILES or None) 8 formView = FormView.get(self, request, *args, **kwargs) 9 listView = ListView.get(self, request, *args, **kwargs) 10 formData = formView.context_data['form'] 11 listData = listView.context_data['object_list'] 12 context = {'form' : formData, 'post_list' : listData} 13 return render(request, 'board/board.html', context) 14 15

試したこと②

class FormAndListView内のobject_listをpost_listに変更いたしました。

python

1 2 3listData = listView.context_data['object_list']→listData = listView.context_data['post_list'] 4 5

試したこと③

class FormAndListView内の下の一文を追加し

python

1 2 3 formset = UploadModelFormSet(request.POST or None, files=request.FILES or None) 4 5

contextにも追加いたしました。

context = { 'formset': formset, }

しかしいずれも送信フォームを押すと'FormAndListView' object has no attribute 'object_list'が出現してしまいます。
フォームからの画像のアップロード自体はListViewとMixさせなければ成功するのですが・・・。
ぜひよろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

python=3.7.0
django=(2, 0, 2, 'final', 0)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ファイル送信したい場合はformタグに enctype="multipart/form-data"をつける必要があります。

投稿2019/01/25 03:43

m.ts10806

総合スコア80842

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sr2460

2019/01/25 03:53

ありがとうございます!!解決しました。
m.ts10806

2019/01/25 03:56

解決されたようで何よりです
m.ts10806

2019/01/25 03:57

一応、なぜ必要となるか、どんな意味があるかは調べて理解を深めておいてください
sr2460

2019/01/25 04:01

はい!! ①普段のformでは使用しない ②以前成功した画像のアップロード時はコピー&ペーストしていたので意識していなかった。 ということで気が付かなかったのだと思います。 今回エラーが出たことで意識付けができましたし、意味を調べることでさらに忘れにくくなると思いますので、アドバイス通り調べて理解を深めようと思います。 本当にどうもありがとうございます!
sr2460

2019/01/25 06:57

デフォルト値でフォームを送信してしまうと画像のURLを探し出せないということでしょうかね。 もう少し論理的に理解したいので学習を進めてまいります。
m.ts10806

2019/01/25 06:58

そもそもファイルはテキストデータではありませんから。 画像のURL云々の話ではなく「ファイルの実体を扱えるかどうか」の話です。
sr2460

2019/01/26 03:59

このリンクを見てファイルデータの実態が送信できない部分は直感的になんとなくはわかるのですが、しっかり理解しようとするとまだまだ時間がかかってしまうかもしれません。 http://mugenup-tech.hatenadiary.com/entry/2014/08/28/100910
m.ts10806

2019/01/26 09:41

そこは「そんなもの」と簡易理解で良いと思います。 仕組みまで突っ込もうと思ったら「そもそも通信とは」というところからになってプログラミングから離れます。
sr2460

2019/01/27 09:32

アドバイスありがとうございます!! 少しづつでも前進できるように頑張っていきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問