Djangoでviewからformにパラメタを渡す方法

Djangoでviewからformにパラメタを渡す方法をご紹介します。

条件

  • Django 2.1.4
  • Python 3.7.0

実装

ここではファイルアップロードのフォームを例にとります。

views.py

ポイントは「def get_form_kwargs(self):」でkwargsに変数を渡すことです。

# views.py抜粋

from django.views.generic.edit import FormView

# ファイルアップロード
class Upload(FormView):
    template_name = 'monitor/upload.html'
    form_class = UploadFileForm

    def get_form_kwargs(self):
        valiables = 'testTest'  # formへ渡す変数
        kwargs = super(Upload, self).get_form_kwargs()
        kwargs.update({'valiables': valiables})
        return kwargs

forms.py

ポイントは「def __init__(self, *args, **kwargs):」にてviewで渡した変数を受け取ることです。
受けっとった変数を用いてバリデーションチェックしたりすることが出来ます。

# forms.py

from django import forms
import os

VALID_EXTENSIONS = ['.csv']


class UploadFileForm(forms.Form):
    file = forms.FileField(
        label='アップロードファイル',
    )

    def __init__(self, *args, **kwargs):
        self.valiables = kwargs.pop('valiables', None)  # viewから変数を取得
        super(UploadFileForm, self).__init__(*args, **kwargs)

    def clean_file(self):
        file = self.cleaned_data['file']
        extension = os.path.splitext(file.name)[1] # 拡張子を取得
        if not extension.lower() in VALID_EXTENSIONS:
            raise forms.ValidationError('csvファイルを選択してください!')
        if not file.name.startswith(self.valiables):
            raise forms.ValidationError('登録対象とは異なるファイル名のcsvファイルです。'
                                        '('+ self.valiables + '.csvを選択してください。)')

テンプレート

<!-- upload.html -->
{% extends 'base.html' %}

{% block content %}

<h1>アップロード サンプル</h1>

<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {% if form.errors %}
        {% for field in form %}
            {% for error in field.errors %}
                <div class="alert alert-danger">
                    <strong>{{ error|escape }}</strong>
                </div>
            {% endfor %}
        {% endfor %}
        {% for error in form.non_field_errors %}
            <div class="alert alert-danger">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
    {% endif %}

    {% for field in form %}
    <div class="form-group form-inline">
        <div class="col-md-8">
            {{ field }}
        </div>
    </div>
    {% endfor %}
    <div class="form-group">
        <button type="submit">アップロード</button>
    </div>
</form>

{% endblock %}

実行結果

Djangoを起動してアップロード画面を開きます。

ファイル選択で「data.csv」というファイルを選択します。

アップロードボタンを押すと、予期したファイル名ではないためバリデーションエラーになります。

参考

Django: pass a variable from a form view to a form

https://gist.github.com/vero4karu/ec0f82bb3d302961503d

コメントを残す

メールアドレスが公開されることはありません。