Я хочу проверить django, если URL-адрес существует, и если это нужно, я хочу показать что-то на экране, то есть:
if URL_THAT_POINTS_TO_SOME_PDF exists
SHOW_SOMETHING
Я хочу проверить 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
в шаблоне - это полностью неправильная часть цикла запрос/ответ, который запускает потенциально длительные операции: рассмотрите, что происходит, если URL-адрес существует, но проблема DNS заставляет urllib2
занять 10 секунд. BAM! Мгновенно 10 дополнительных секунд на загрузке страницы.
Я бы сказал, что самая лучшая практика для создания возможно длительных задач, таких как асинхронная (и, следовательно, не блокировка загрузки страницы), использует django-celery
; там базовое учебное пособие, которое охватывает использование pycurl
для проверки веб-сайта, или вы можете посмотреть как Саймон Уиллисон реализовал задачи сельдерея (слайды 32-41) для аналогичной цели на Lanyrd.
Требуется дополнительно:
из django.core.exceptions import ValidationError
чтобы он работал у меня. Просто говорю: 0)
Проблема
from django.core.validators import URLValidator
говорит, что www.google.ro
недействителен. Что неправильно в моей точке зрения. Или, по крайней мере, недостаточно.
Как его решить?
Ключ. Посмотрите на исходный код для models.URLField
, вы увидите, что он использует forms.FormField
как валидатор. Что больше, чем URLValidator
сверху
Решение
Если я хочу проверить a url
как http://www.google.com
или как www.google.ro
, я бы сделал следующее:
из django.forms import URLField
def validate_url(url):
url_form_field = URLField()
try:
url = url_form_field.clean(url)
except ValidationError:
return False
return True
Я нашел это полезным. Может быть, это помогает кому-то другому.
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")