フォーム入力エラーのとき、フォームを再描画してエラーメッセージを表示することになりますが、ファイルのアップロードがある場合、その入力値はクリアされますので、もう一度選ぶことになります。
django-file-resubmitはファイルをキャッシュにキープして、再入力する手間を省けるようにするライブラリです。
un1t/django-file-resubmit · GitHub
インストール
pip install django-file-submit
INSTALLED_APPSにfile_resubmitを追加
INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.admin', 'apps', 'file_resubmit' )
cacheの設定を追加します
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', }, "file_resubmit": { 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', "LOCATION": '/tmp/file_resubmit/' }, }
MEIDA_ROOTとか
import os PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'upload') MEDIA_URL = 'http://localhost:8000/upload/'
modelに画像フィールドをもたせます。
models.py
class Person(models.Model): name = models.CharField(max_length=100) icon = ImageField(upload_to='/tmp/icons') @models.permalink def get_absolute_url(self): return ('apps_person_detail', (), {'pk': self.pk})
formでwidgetを指定します。
forms.py
class PersonForm(forms.ModelForm): class Meta: model = Person widgets = { 'icon': AdminResubmitImageWidget(), }
views.py
class PersonCreateView(CreateView): model = Person form_class = PersonForm class PersonDetailView(DetailView): model = Person
テンプレート
画像をアップロードするのでenctype="multipart/form-data"を忘れずに追加
person_form.html
{% extends "base.html" %} {% block content %} {% if form.errors %}<h1>Please correct the following errors</h1>{% else %}<h1>Submit</h1>{% endif %} <form enctype="multipart/form-data" action="" method="post">{% csrf_token %} <table> {{ form }} </table> <p><input type="submit" value="submit" /></p> </form> {% endblock %}
person_detail.html
{% extends "base.html" %} {% block content %} <p>{{ object.name }}</p> <p><img src="{{ object.icon.url }}" /></p> {% endblock %}
urls.py
url(r'^person/create/?$', PersonCreateView.as_view(), name='apps_person_create'), url(r'^person/(?P<pk>\d+?)/$', PersonDetailView.as_view(), name='apps_person_detail'), url(r'^upload/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}),
使ってみる
画像名が表示されているのが確認できます。
nameをいれてsubmit
保存されました!