【Django チュートリアル】 forms.Form.is_multipart() を徹底解説! ファイルアップロードの可否を判断する方法


django.forms.Form.is_multipart() は、Django フォームがファイルアップロードを含むかどうかを判断するメソッドです。ファイルアップロードを含むフォームは、multipart/form-data エンコーディングを使用して送信する必要があります。

使い方

form = MyForm()
if form.is_multipart():
    # フォームはファイルアップロードを含む
    pass
else:
    # フォームはファイルアップロードを含まない
    pass

次の例では、ContactForm フォームに ImageField フィールドが含まれているため、is_multipart() メソッドは True を返します。

from django.forms import ModelForm
from .models import Contact

class ContactForm(ModelForm):
    class Meta:
        model = Contact
        fields = ['name', 'email', 'mugshot']

form = ContactForm()
if form.is_multipart():
    # フォームはファイルアップロードを含む
    pass
else:
    # フォームはファイルアップロードを含まない
    pass

テンプレートでの使用

テンプレートでは、form.is_multipart() メソッドを使用して、フォームのエンコーディングタイプを動的に設定できます。

{% if form.is_multipart %}
<form enctype="multipart/form-data" method="post" action="/contact/">
{% else %}
<form method="post" action="/contact/">
{% endif %}

{{ form }}

</form>

forms.Form.is_multipart() メソッドは、ファイルアップロードを含むかどうかを判断するのに役立ちます。これは、フォームのエンコーディングタイプを動的に設定したり、ファイルアップロードに対応するロジックを実装したりするのに役立ちます。

  • django.forms.Form.is_multipart() メソッドは、Django のバージョン 1.4 以降で使用できます。


ファイルアップロードを含むフォーム

from django.forms import ModelForm
from .models import Contact

class ContactForm(ModelForm):
    class Meta:
        model = Contact
        fields = ['name', 'email', 'mugshot']

form = ContactForm()

if form.is_multipart():
    # フォームはファイルアップロードを含む
    print("ファイルアップロードを含むフォーム")
    # ファイル処理などのロジック
else:
    # フォームはファイルアップロードを含まない
    print("ファイルアップロードを含まないフォーム")
    # ファイルアップロードなしの処理
{% if form.is_multipart %}
<form enctype="multipart/form-data" method="post" action="/contact/">
{% else %}
<form method="post" action="/contact/">
{% endif %}

{{ form }}

</form>
  • 上記のコードはあくまで例であり、実際の用途に合わせて変更する必要があります。


forms.Form.is_multipart() メソッドは、ファイルアップロードを含むかどうかを判断するのに役立ちますが、いくつかの代替方法があります。状況によっては、これらの代替方法の方が適切な場合があります。

代替方法

  1. request.methodrequest.FILES をチェックする
from django.http import HttpRequest

def my_view(request: HttpRequest):
    if request.method == 'POST':
        if request.FILES:
            # フォームはファイルアップロードを含む
            pass
        else:
            # フォームはファイルアップロードを含まない
            pass
    else:
        # GET リクエスト
        pass
  1. form.cleaned_data をチェックする
from django.forms import Form

class MyForm(Form):
    file_field = forms.FileField()

form = MyForm(data=request.POST, files=request.FILES)

if form.is_valid():
    if form.cleaned_data['file_field']:
        # ファイルアップロードを含む
        pass
    else:
        # ファイルアップロードを含まない
        pass
  1. form.has_changed()form.initial_data をチェックする
from django.forms import Form

class MyForm(Form):
    file_field = forms.FileField()

form = MyForm(data=request.POST, files=request.FILES)

if form.has_changed() and 'file_field' in form.changed_data:
    # ファイルアップロードを含む
    pass
elif form.initial_data.get('file_field'):
    # フォームはファイルアップロードを含むが、変更されていない
    pass
else:
    # フォームはファイルアップロードを含まない
    pass

それぞれの方法の長所と短所

方法長所短所
request.methodrequest.FILES をチェックするシンプルファイルアップロード以外のデータも処理する必要がある場合、冗長になる可能性がある
form.cleaned_data をチェックするフォームの検証処理と統合できるファイルアップロードが検証エラーの場合、判断できない
form.has_changed()form.initial_data をチェックするフォームの変更履歴に基づいて判断できるファイルアップロードが変更されていない場合、判断できない

どの方法を使用するかは、状況によって異なります。シンプルな方法が必要な場合は、request.methodrequest.FILES をチェックする方法が適しています。フォームの検証処理と統合したい場合は、form.cleaned_data をチェックする方法が適しています。フォームの変更履歴に基づいて判断したい場合は、form.has_changed()form.initial_data をチェックする方法が適しています。

  • 上記の代替方法は、すべて Django のバージョン 1.4 以降で使用できます。