Как я могу проверить, существует ли URL с валидаторами Django? - PullRequest
19 голосов
/ 03 июля 2010

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

if URL_THAT_POINTS_TO_SOME_PDF exists 
     SHOW_SOMETHING

Ответы [ 7 ]

47 голосов
/ 03 июля 2010

Изменить: Обратите внимание, что это больше не действует для любой версии Django выше 1,5

Я предполагаю, что вы хотите проверить, существует ли файл на самом деле, а не если есть толькоobject (который является простым оператором 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 и вперед вы идете.

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

5 голосов
/ 21 августа 2012

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

2 голосов
/ 19 января 2017

Задача

from django.core.validators import URLValidator говорит, что www.google.ro недействительно. Что неправильно с моей точки зрения. Или, по крайней мере, недостаточно.

Как ее решить?

Ключ к просмотру исходного кода для models.URLField, вы увидите, что он использует forms.FormField в качестве валидатора. Который делает больше чем URLValidator сверху

Решение

Если я хочу проверить 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

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

2 голосов
/ 30 июля 2010

Потребовалось еще:

из django.core.exceptions import ValidationError

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

1 голос
/ 17 мая 2012
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://. Интересно, это так?

0 голосов
/ 03 февраля 2017

См: 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")
0 голосов
/ 23 ноября 2016

Я не видел здесь ответа. Это может быть полезно для кого-то еще.

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