]>
<< FedoraにBerylをインストールmemo | main | interact >>
RSSを登録する際、そのURIがRSSのものかを判定したい。フォーム入力内容の確認を行うには、バリデータを使えばいいようだ。validators.pyにはよく使われそうないくつかのバリデータが定義されているが、ここではfeedparserが拾ってくるversionによって判別を行うものを作ってみることにした。
Django オンラインドキュメント和訳: フォームとフィールド,マニピュレータ
UNIVERSAL FEED PARSER: Feed Type and Version Detection
feedparserによってRSSのversionが判別できないと空列が返ってくるので、そのときはValidationErrorを投げてやればよい。models.pyを少し書き換える。
from django.db import models
from django.core import validators
import feedparser
# Create your models here.
class Site(models.Model):
title = models.CharField(blank=True, maxlength=100)
rss = models.URLField(blank=False, verify_exists=True, maxlength=100)
last = models.DateTimeField(auto_now_add=True)
def save(self):
f = feedparser.parse(self.rss)
if not f.version :
raise validators.ValidationError("URL is not valid RSS")
if not self.title:
self.title = f.feed.title.encode('utf-8')
super(Site, self).save()
def __str__(self):
return self.rss
class Admin:
list_display = ('title', 'rss', 'last')
しかし、これではValidationErrorが適切にキャッチされず、入力が不適切な場合django自体のエラー画面が出力されてしまう。これを防ぐにはモデルのそれぞれのフォームを定義する際にバリデータのリストを引数として渡してやるのがよいようだ。例えばアルファベット小文字のみを入力とする属性hogeは、django/core/validators.pyで定義されたバリデータisLowerCaseを使って
hoge = models.CharField(maxlength=100, validator_list=[isLowerCase])
と書くことができる。
validators.pyにおいて、isLowerCaseの実装は
def isLowerCase(field_data, all_data):
if field_data.lower() != field_data:
raise ValidationError, gettext("Uppercase letters are not allowed here.")
となっているので、同様に入力がRSSであるか判定するバリデータisRSSが書ける。
def isRSS(field_data, all_data):
f = feedparser.parse(field_data)
if not f.version :
raise validators.ValidationError("URL is not valid RSS")
rss = models.URLField(blank=False, verify_exists=True, \
maxlength=100, validator_list=[isRSS])
raiseをlambda式中に埋め込めればなあ…。
ついでに、RSSのURIはユニークになるはずなのでunique=Trueにしておく。Django1.0でDateTimeFieldのauto_now_addがなくなるようなのでそちらも修正。
from django.db import models
from django.core import validators
import datetime
import feedparser
def isRSS(field_data, all_data):
f = feedparser.parse(field_data)
if not f.version :
raise validators.ValidationError("URL is not valid RSS")
#Create your models here.
class Site(models.Model):
title = models.CharField(blank=True, maxlength=100)
rss = models.URLField(blank=False, unique=True, verify_exists=True, \
maxlength=100, validator_list=[isRSS])
last = models.DateTimeField(null=True)
def save(self):
f = feedparser.parse(self.rss)
if not self.title:
self.title = f.feed.title.encode('utf-8')
self.last = datetime.datetime.now()
super(Site, self).save()
http://www.panopticon.jp/mt/mt-tb.cgi/80
コメントする