チェックインしたいDjango URLが存在するかどうか、存在する場合は画面に何かを表示したい、つまり:
if URL_THAT_POINTS_TO_SOME_PDF exists
SHOW_SOMETHING
編集:これはDjango 1.5以上のバージョンでは無効になっていることに注意してください
オブジェクトだけではなく、ファイルが実際に存在するかどうかを確認したいと思います(これは単純なifステートメントです)
まず、Djangoのソースコードを常に確認することをお勧めします。 いくつかの優れたコードを見つける 使用できるからです:)
テンプレート内でこれを実行したいと思います。 URLを検証するための組み込みのテンプレートタグはありませんが、基本的にはテンプレートタグ内でそのURLValidator
クラスを使用してテストできます。単に:
from Django.core.validators import URLValidator
from Django.core.exceptions import ValidationError
validate = URLValidator(verify_exists=True)
try:
validate('http://www.somelink.com/to/my.pdf')
except ValidationError, e:
print e
URLValidator
クラスは、リンクを開くことができない場合、ValidationError
を吐き出します。それは使用しています urllib2
実際にリクエストを開いて、基本的な正規表現チェックを使用するだけではありません(ただし、それも実行します)。
これをカスタムテンプレートタグに入れることができます。これは、Djangoドキュメントで作成する方法を見つけることができます。
それがあなたのスタートであることを願っています。
verify_exists
パラメータからDjango.core.validators.URLValidator
に基づくものはすべて、Django 1.5 — ドキュメント はこれについて何も述べていませんが、- ソースコード 1.4(最新の安定バージョン)でそのメカニズムを使用すると、DeprecationWarning
につながることがわかります( 開発バージョンでは完全に削除されています =):
if self.verify_exists:
import warnings
warnings.warn(
"The URLField verify_exists argument has intractable security "
"and performance issues. Accordingly, it has been deprecated.",
DeprecationWarning
)
このメソッドには、HEAD
リクエストを使用してURLをチェックするという奇妙な癖もあります。帯域幅効率は確かですが、一部のサイト(Amazonなど)はエラーで応答します(HEAD
、ここで同等のGET
は問題ありませんでした)、これは バリデーターからの偽陰性の結果 につながります。
また、テンプレートでurllib2
を使用して何もしないことをお勧めします(2年間で大幅に変更されました)。これは、実行が長くなる可能性のある操作をトリガーする要求/応答サイクルの完全に間違った部分です。 URLが存在するが、DNSの問題により、urllib2
がそれを解決するのに10秒かかる場合。バム!ページの読み込み時に10秒余分にかかります。
このような非同期の可能性のある長時間実行タスクを作成する(したがってページの読み込みをブロックしない)ための現在のベストプラクティスは、Django-celery
を使用することです。 基本的なチュートリアルpycurl
を使用してWebサイトをチェックする方法、または Simon Willisonがセロリタスクを実装した方法 (スライド32-41) Lanyrdの同様の目的。
問題
from Django.core.validators import URLValidator
は、www.google.ro
が無効であることを示しています。私の見解ではどちらが間違っています。または少なくとも十分ではありません。
それを解決する方法は?
手がかりは、models.URLField
のソースコードを調べることです。バリデーターとしてforms.FormField
を使用していることがわかります。上からURLValidator
以上のことをします
解決策
http://www.google.com
やwww.google.ro
のようなurl
を検証したい場合は、次のようにします。
django.formsからインポートURLField
def validate_url(url):
url_form_field = URLField()
try:
url = url_form_field.clean(url)
except ValidationError:
return False
return True
これは便利だと思いました。多分それは他の誰かを助けます。
追加が必要でした:
django.core.exceptionsからimportValidationError
それが私のために働くために。ただ言う; 0)
_from Django.core.validators import URLValidator
from Django.core.exceptions import ValidationError
validate = URLValidator(verify_exists=True)
value = request.GET.get('url', None)
if value:
try:
validate(value)
except ValidationError, e:
print e
_
validate(value)
は、URLの前に_http://
_のようなスキーマがない場合は失敗します。それは仕様によるものなのだろうか。
私はここで答えを見ていません。それは他の誰かに役立つかもしれません。
from Django import forms
f = forms.URLField()
try:
f.clean(http://example.com)
print "valid url"
except:
print "invalid url"
参照: http://www.agmweb.ca/2009-04-19-Django-urlpatterns---its-more-than-just-urls/
Django 1.10で私は今使用します:
from Django.core.urlresolvers import RegexURLResolver, Resolver404
if 'next' in request.GET.keys():
n = request.GET["next"].strip('/') + "/"
resolver = RegexURLResolver(r'', urls)
try:
callback, callback_args, callback_kwargs = resolver.resolve(n)
return HttpResponseRedirect(str(request.GET["next"]))
except Resolver404:
raise PermissionDenied("This page is not available")