はじめに
Djangoを用いてユーザーがアップロードした動画を受け取るシステムを作成していた際にis_valid()
がTrue
にならない論理エラーが発生しました。本記事ではis_valid()
に関するエラーとその解決法について記述します。なお、使用しているDjangoのバージョンは5.0.6
で、pythonのバージョンは3.11.1
です。
is_valid()とは
django公式ドキュメントによると、データが入力されてform
のインスタンスに対してis_valid()
はデータが正しいかどうかをブール値で返します。form.is_valid()
とすることでformに対して検証を行うことができます。
関連コード
def file_upload(request):
print("GGG")
if request.method == 'POST':
print("FFF")
form = UploadFileForm(request.POST, request.FILES)
print(form.is_valid())
if form.is_valid():
print("AAA")
file_obj = request.FILES['file']
if file_obj:
print("BBB")
handle_uploaded_file(file_obj)
return render(request, 'file_upload/frontpage.html', {
'form': form, 'show_success_message': True
})
else:
return render(request, 'file_upload/frontpage.html', {
'form': form, 'error_message': 'ファイルを選択していません。'
})
else:
form = UploadFileForm()
return render(request, 'file_upload/frontpage.html', {'form': form})
from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()
from django.urls import path,include
from . import views
app_name = 'file_upload'
urlpatterns = [
path('', views.file_upload, name='file_upload'),
path('process/', views.processing, name='processing'),
path('feedback/', include('feedback.urls')),
]
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ファイルアップロード</title>
<style>
body {
font-family: Arial, sans-serif;
}
.header {
text-align: left;
font-size: 2em;
margin: 20px;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80vh;
}
.file-title {
font-size: 1.5em;
margin-bottom: 20px;
}
.file-upload {
margin-bottom: 20px;
}
.file-upload input {
margin-bottom: 10px;
}
.process-btn {
margin-top: 20px;
}
.error-message {
color: red;
margin-top: 10px;
}
</style>
<script>
function showSuccessMessage() {
alert('ファイルが正常にアップロードされました!');
}
function showErrorMessage() {
alert('ファイルを選択していません。');
}
</script>
</head>
<body>
<div class="header">
preai
</div>
<div class="container">
<div class="file-title">
ファイルを選択してください
</div>
<form id="uploadForm" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="file-upload">
{{ form.file }}
<button type="submit">アップロード</button>
</div>
{% if error_message %}
<div class="error-message">{{ error_message }}</div>
{% endif %}
</form>
<div class="process-btn">
<form action="{% url 'file_upload:processing' %}" method="get">
<button type="submit">処理</button>
</form>
</div>
</div>
{% if show_success_message %}
<script>
showSuccessMessage();
</script>
{% endif %}
</body>
</html>
原因と解決策
タイトルを受け取っていないのが原因
タイトルを動画の名前だと勘違いしておりタイトルを受け取るフォームを作っていませんでした。タイトルやファイルを受け取れている場合は出力にちゃんとその文字列が含まれるので勘違いしないように気を付けてください。print(request.POST)
,print(request.FILES
として表示した結果を以下に示します。
タイトルを受け取っていない場合の出力
フォームのデータ: <QueryDict: {'csrfmiddlewaretoken': ['bEDtPv2b7fUsZ1miO25yHG3rmqiFZqmdZo9MBgJZnYFoV8x9QiRXgiGPK4sj8QPo']}>
アップロードされたファイル: <MultiValueDict: {'file': [<TemporaryUploadedFile: demo.mp4 (video/mp4)>]}>
タイトルを受け取っている場合の出力
フォームのデータ: <QueryDict: {'csrfmiddlewaretoken': ['QvsPSGH9hL0TnTsPOozaaBoqdYneY3EdEfY8EroXxuLPj0DGQElzJd1OBCxS7t7o'], 'title': ['demo']}>
アップロードされたファイル: <MultiValueDict: {'file': [<TemporaryUploadedFile: demo.mp4 (video/mp4)>]}>
フォームのデータの最後にtitle
タグが追加されていることが分かります。
解決策
タイトルを受け取っていないためmodels.py
とforms.py
を変更して完了。無事に動画を受け取れるようになりました。また、models.py
で形式を指定してforms.py
ではforms.ModelForm
として参照するように設定しました。
from django import forms
from file_upload.models import Post
class UploadFileForm(forms.ModelForm):
class Meta:
model = Post
fields = ('file', )
from django.db import models
class Post(models.Model):
file = models.FileField()
解決後のコード
いかにgithubのリンクを貼っておきます。今回のエラーはfile_uploadファイル内で起こっています。
参照したサイト