ファイルアップロードとフォーマットチェックの方法

91 views
Skip to first unread message

Sato

unread,
May 18, 2009, 7:41:59 PM5/18/09
to django-ja
初めましてSatoと申します。

私は現在ファイルアップロード時のフォーマットチェックを行いたいと思っています。
(作成したサイトは仮にsampleとします。)
1:ログイン画面からログイン
2:管理画面からsampleサイトに遷移
3:sampleサイトで、必要な情報の入力とアップロードファイル選択
4:保存押下時にアップロードするファイルのフォーマットチェック
5:問題なければ登録。問題ありの場合、エラーメッセージ。

上記より、アップロードやその情報の登録は上手く出来ました。
(4:のフォーマットチェックを除いた状態)

構成は仮にsampleとすると、以下になります。
sample
→admin.py :clean_・・・を記述
→model.py :FileField他定義
→view.py :空

ここで、最初はclean_XXXを使用し、validateチェックしようとしましたが、
ファイルパスはとってこれても、アップロードした情報は取ってくる方法が思いつかず、
断念してしまいました。
次にview.pyを作成し、そこで、検証を行おうと思ったのですが、
エラーの場合に何を返すのか、チェックはどのタイミングで行うのが一番よいか
確定できず、断念いたしました。
また、フォーマットのチェックは、util.pyに関数を作成し、それを呼び出す予定でした。

参考にしたサイト、本は以下になります。
http://djangoproject.jp/doc/ja/1.0/topics/http/file-uploads.html
LLフレームワークブック DjangoXPython

上記より、アップロードのチェックをどのように行うことがdjangoとして一番理想的であるか、
ご教示いただきたく投稿させていただきました。

#djangoのversionは1.0.2になります。

お忙しい中恐縮ですが、宜しくお願い致します。


tsuyuki makoto

unread,
May 19, 2009, 11:34:20 AM5/19/09
to djan...@googlegroups.com
露木です。

viewsを作り、管理画面以外からも使うことを想定しているのであれば、
ModelFormとAdminFormの両方に対応できる形で実装すれば良いの
ではないでしょうか。

ファイルフィールドの話は良く出てくるので、試しにそれっぽい実装をしてみました。
仮にアプリケーション名をffとしています。もちろんいろいろ手抜きです。

ff/models.py
---------------------------------
from django.db import models

class TestModel(models.Model):
name = models.CharField(max_length=20)
test_file = models.FileField(upload_to='test')


django.forms.FileFieldを継承してファイルの中身を検証するフィールドと
そのフィールドをTestModelのtest_fileに対して適用するためのモデルフォーム。
基本的にImageFieldの丸パクリです。
Djangoに慣れてきたらDjango自体がどうしているのか、コードを読むと
開発効率が上がると思います。
http://code.djangoproject.com/browser/django/tags/releases/1.0.2/django/forms/fields.py

ff/forms.py
---------------------------------
#coding:utf-8
from django import forms
from ff.models import TestModel

from StringIO import StringIO

class ForbiddenEveresFileField(forms.FileField):
def clean(self, data, initial=None):
f = super(ForbiddenEveresFileField, self).clean(data, initial)
if f is None:
return None
elif not data and initial:
return initial

if hasattr(data, 'temporary_file_path'):
file = data.temporary_file_path()
else:
if hasattr(data, 'read'):
file = StringIO(data.read())
else:
file = StringIO(data['content'])
for l in file:
if 'everes' in l: #不正なフォーマットだった場合
raise forms.ValidationError('Invalid Format')
return f

class TestForm(forms.ModelForm):
test_file = ForbiddenEveresFileField()
class Meta:
model = TestModel

アドミンフォームにモデルフォームを指定して、それからアドミンフォームと
モデルをひもづける。

ff/admin.py
---------------------------------
from django.contrib import admin
from ff.models import TestModel
from ff.forms import TestForm

class TestAdmin(admin.ModelAdmin):
form = TestForm
class Meta:
model = TestModel

admin.site.register(TestModel, TestAdmin)

とりあえず管理画面でだけ使う場合には、TestFormのclass Metaは不要なはず。
もっとごりごりやる方法もあるでしょうが、基本は以下だと思います。

* 入力値単体で検証できるValidationはFormやFormのFieldで行う
(これはDjangoに限らず、Webアプリケーション構築全般で真と
されてる気がします)

以上、参考になれば

2009/05/19 8:41 Sato <maip...@kiwi.ne.jp>:

Reply all
Reply to author
Forward
0 new messages