Подтвердить что ты не робот

Как проверить, существует ли URL с валидаторами Djangos?

Я хочу проверить django, если URL-адрес существует, и если это нужно, я хочу показать что-то на экране, то есть:

if URL_THAT_POINTS_TO_SOME_PDF exists 
     SHOW_SOMETHING
4b9b3361

Ответ 1

Изменение: Обратите внимание, это больше не действует для любой версии 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, и все готово.

Надеюсь, это начало для вас.

Ответ 2

Все, что основано на параметре 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.

Ответ 3

Требуется дополнительно:

из django.core.exceptions import ValidationError

чтобы он работал у меня. Просто говорю: 0)

Ответ 4

Проблема

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

Я нашел это полезным. Может быть, это помогает кому-то другому.

Ответ 5

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://. Интересно, это по дизайну.

Ответ 6

Я не видел ответа здесь. Это может помочь кому-то другому.

from django import forms
f = forms.URLField()
try:
    f.clean(http://example.com)
    print "valid url"
except:
    print "invalid url"

Ответ 7

См: 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")