如何检查Django验证器是否存在URL?

时间:2010-07-03 03:41:01

标签: django url url-validation

我想检查django是否存在URL,如果存在,我想在屏幕上显示某些内容,即:

if URL_THAT_POINTS_TO_SOME_PDF exists 
     SHOW_SOMETHING

7 个答案:

答案 0 :(得分:46)

编辑:请注意,这不再适用于1.5以上的任何版本的Django

我假设您要检查文件是否确实存在,而不是只有一个对象(这只是一个简单的if语句)

首先,我建议您一直浏览Django的源代码,因为您可以使用find some great code:)

我假设您想在模板中执行此操作。没有用于验证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文档中创建,然后离开。

希望这是一个开始。

答案 1 :(得分:5)

基于verify_exists参数django.core.validators.URLValidator的任何内容都将停止使用Django 1.5 - the documentation对此有所帮助,但source code显示使用该机制1.4(最新的稳定版本)会导致DeprecationWarning(您会看到it has been removed completely in the development version):

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 - 带宽效率,当然,但有些网站(如亚马逊)会回复错误(到{ {1}},等效的HEAD可能会很好),这会导致false negative results from the validator

我也会(在两年内发生了很多变化)建议不要在模板中使用GET执行任何操作 - 这完全是请求/响应周期中触发可能长时间运行操作的错误部分:考虑如果URL确实存在会发生什么,但DNS问题导致urllib2需要10秒才能解决问题。 BAM!在您的页面加载上立即增加10秒。

我想说目前使用可能长时间运行的任务的最佳做法是异步(因此不阻止页面加载)正在使用urllib2; a basic tutorial涵盖使用django-celery来检查网站,或者您可以在Lanyrd上查看how Simon Willison implemented celery tasks(幻灯片32-41)以达到类似目的。

答案 2 :(得分:2)

这需要额外的:

来自django.core.exceptions import ValidationError

让它为我工作。只是说; 0)

答案 3 :(得分:2)

问题

from django.core.validators import URLValidatorwww.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

我觉得这很有用。也许它可以帮助别人。

答案 4 :(得分:1)

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)之类的架构,则

http://会失败。我想知道这是不是设计。

答案 5 :(得分:0)

我这里没有看到答案。它可能对其他人有帮助。

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

答案 6 :(得分:0)

请参阅: 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")