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

发布于 2024-09-08 05:37:25 字数 136 浏览 7 评论 0原文

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

if URL_THAT_POINTS_TO_SOME_PDF exists 
     SHOW_SOMETHING

I want to check in django if a URL exists and if it does I want to show something on screen, i.e.:

if URL_THAT_POINTS_TO_SOME_PDF exists 
     SHOW_SOMETHING

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

淡莣 2024-09-15 05:37:25

编辑:请注意,这对于 1.5 以上的 Django 版本不再有效

我假设您想检查文件是否确实存在,而不是是否只有一个对象(这只是一个简单的 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 as e:
    print(e)

URLValidator 类在无法打开链接时会抛出 ValidationError。它使用 urllib2 来实际打开请求,因此它不仅仅是使用基本的正则表达式检查(但它也这样做。)

您可以将其放入自定义模板标记中,您将了解如何在Django 文档就可以了。

希望这对您来说是一个开始。

Edit: Please note, this is no longer valid for any version of Django above 1.5

I assume you want to check if the file actually exists, not if there is just an object (which is just a simple if statement)

First, I will recommend always looking through Django's source code because you will find some great code that you could use :)

I assume you want to do this within a template. There is no built-in template tag to validate a URL but you could essentially use that URLValidator class within a template tag to test it. Simply:

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 as e:
    print(e)

The URLValidator class will spit out the ValidationError when it can't open the link. It uses urllib2 to actually open the request so it's not just using basic regex checking (But it also does that.)

You can plop this into a custom template tag, which you will find out how to create in the django docs and off you go.

Hope that is a start for you.

潜移默化 2024-09-15 05:37:25

问题

from django.core.validators import URLValidator 表示 www.google.ro 无效。在我看来这是错误的。或者至少还不够。

如何解决?

线索是查看models.URLField的源代码,你会发现它使用forms.FormField作为验证器。 它的作用比上面的

解决方案

如果我想验证像 http://www.google.com< 这样的 url , 中的 URLValidator 还要多。 /code> 或像 www.google.ro 一样,我会执行以下操作:

from 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

我发现这很有用。也许它对其他人有帮助。

Problem

from django.core.validators import URLValidator says that www.google.ro is invalid. Which is wrong in my point of view. Or at least not enough.

How to solve it?

The clue Is to look at the source code for models.URLField, you will see that it uses forms.FormField as a validator. Which does more than URLValidator from above

Solution

If I want to validate a url like http://www.google.com or like www.google.ro, I would do the following:

from 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

I found this useful. Maybe it helps someone else.

猫卆 2024-09-15 05:37:25

任何基于 django.core.validators.URLValidatorverify_exists 参数的内容都将停止与 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 秒才能解决该问题,会发生什么情况。嘭!页面加载时间立即延长 10 秒。

我想说,目前制作像这样的异步任务(因此不会阻止页面加载)的可能长时间运行的任务的最佳实践是使用 django-celery ;有基本教程,其中介绍了使用pycurl来检查网站,或者您可以查看 Simon Willison 如何实现 celery 任务(幻灯片 32-41 )在 Lanyrd 上也有类似的目的。

Anything based on the verify_exists parameter to django.core.validators.URLValidator will stop working with Django 1.5 — the documentation helpfully says nothing about this, but the source code reveals that using that mechanism in 1.4 (the latest stable version) leads to a DeprecationWarning (you'll see 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
        )

There are also some odd quirks with this method related to the fact that it uses a HEAD request to check URLs — bandwidth-efficient, sure, but some sites (like Amazon) respond with an error (to HEAD, where the equivalent GET would have been fine), and this leads to false negative results from the validator.

I would also (a lot has changed in two years) recommend against doing anything with urllib2 in a template — this is completely the wrong part of the request/response cycle to be triggering potentially long-running operations: consider what happens if the URL does exist, but a DNS problem causes urllib2 to take 10 seconds to work that out. BAM! Instant 10 extra seconds on your page load.

I would say the current best practice for making possibly-long-running tasks like this asynchronous (and thus not blocking page load) is using django-celery; there's a basic tutorial which covers using pycurl to check a website, or you could look into how Simon Willison implemented celery tasks (slides 32-41) for a similar purpose on Lanyrd.

脱离于你 2024-09-15 05:37:25

它需要额外的:

from django.core.exceptions import ValidationError

才能为我工作。只是说;0)

It took an additional:

from django.core.exceptions import ValidationError

for it to work for me. Just saying ;0)

心的憧憬 2024-09-15 05:37:25
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

如果 url 前面没有类似 http:// 的架构,则 validate(value) 会失败。我想知道这是否是设计使然。

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) fails if the url is not preceeded with a schema like http://. I wonder if that is by design.

原谅过去的我 2024-09-15 05:37:25

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

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

I have not seen the answer here. It might helpful to someone else.

from django import forms
f = forms.URLField()
try:
    f.clean(http://example.com)
    print "valid url"
except:
    print "invalid url"
明媚如初 2024-09-15 05:37:25

对于新版本的 Django,您应该在给出无效 url 时引发验证异常 django.core.exceptionValidationError

from django.core.validators import URLValidator                                                                                                                             
validate = URLValidator()                                                                                                                                                                  
validate('http://www.google.com')                                                                                                                                                                
validate('http://www2.google.com')                                                                                                                                                               
validate('httpAA://www2.google.com')                                                                                                                                                             
     Traceback (most recent call last):                                                                                                                                                                     
     File "<console>", line 1, in <module>                                                                                                                                                                
     File "/etl/.venv/lib/python3.8/site- 
     packages/django/core/validators.py", line 110, in __call__                                                                                                         
     raise ValidationError(self.message, code=self.code, params={'value': value})                                                                                                                     
     django.core.exceptions.ValidationError: ['Enter a valid URL.']

For new version of Django, you should just when a non valid url is given it raises a Validation exception django.core.exceptionValidationError

from django.core.validators import URLValidator                                                                                                                             
validate = URLValidator()                                                                                                                                                                  
validate('http://www.google.com')                                                                                                                                                                
validate('http://www2.google.com')                                                                                                                                                               
validate('httpAA://www2.google.com')                                                                                                                                                             
     Traceback (most recent call last):                                                                                                                                                                     
     File "<console>", line 1, in <module>                                                                                                                                                                
     File "/etl/.venv/lib/python3.8/site- 
     packages/django/core/validators.py", line 110, in __call__                                                                                                         
     raise ValidationError(self.message, code=self.code, params={'value': value})                                                                                                                     
     django.core.exceptions.ValidationError: ['Enter a valid URL.']
听,心雨的声音 2024-09-15 05:37:25

看:
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")

See:
http://www.agmweb.ca/2009-04-19-django-urlpatterns---its-more-than-just-urls/

In django 1.10 i now use:

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")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文