Django的URL字段测试问题

时间:2011-04-08 00:16:03

标签: django django-models

有人可以澄清为什么这个URL http://www.nacolmeia.com.br/do/Home/oferta/EnER没有被从URLField的Django生成的表单中接受吗?

:)

由于

2 个答案:

答案 0 :(得分:8)

您是否在尝试验证网站的同一台服务器上托管该网站? docs

  

请注意,当您使用时   单线程开发服务器,   验证由服务提供的URL   相同的服务器将挂起。这不应该   是多线程的问题   服务器

它看起来不像表单级别的验证失败

>>> from django import forms
>>> f = forms.URLField()
>>> f.clean('http://www.nacolmeia.com.br/do/Home/oferta/EnER')
u'http://www.nacolmeia.com.br/do/Home/oferta/EnER'
>>> f.clean('sadfas')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/dev/.virtualenvs/thepidb/lib/python2.7/site-packages/django/forms/fields.py", line 171, in clean
    self.run_validators(value)
  File "/home/dev/.virtualenvs/thepidb/lib/python2.7/site-packages/django/forms/fields.py", line 160, in run_validators
    raise ValidationError(errors)
ValidationError: [u'Enter a valid URL.']
>>> 

如果您不需要在models.py

中验证网站没有返回404
url = models.URLField(verify_exists=False)

修改

在django源代码here中进行了一些挖掘后,有些人在使用shell时,我仍然不确定为什么带有大写字母的网址会导致重定向循环。

>>> from django.core.validators import URLValidator
>>> u = URLValidator(verify_exists=True)
>>> u.__call__('http://www.nacolmeia.com.br/do/Home/oferta/EnER')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/dev/.virtualenvs/thepidb/lib/python2.7/site-packages/django/core/validators.py", line 105, in __call__
    raise broken_error
ValidationError: [u'This URL appears to be a broken link.']
>>> u.__call__('http://www.nacolmeia.com.br/do/home/oferta/ener')
>>> 

引发的实际异常是HTTPError:

  File "/usr/lib/python2.7/urllib2.py", line 606, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python2.7/urllib2.py", line 398, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 511, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 430, in error
    result = self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 370, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 606, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
  File "/usr/lib/python2.7/urllib2.py", line 398, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 511, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 430, in error
    result = self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 370, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 596, in http_error_302
    self.inf_msg + msg, headers, fp)
HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.
The last 30x error message was:
Found
>>> 

这里有一些关于HTTPError的帖子:herehere

好像它与cookies有关,但我无法提供一个好的解释,我会把它留给其他人。

如果您不想关闭验证但不关心网址大小写,则可能有效的解决方法是覆盖表单的clean_field方法。

def clean_your_url_field(self):
    return self.cleaned_data['your_url_field'].lower()

答案 1 :(得分:0)

我想我发现了这个问题。当您打开此网址时:

http://www.nacolmeia.com.br/do/Home/oferta/EnER

...它会重定向到此网址:

http://www.nacolmeia.com.br/do/Home/oferta/EnER/piracicaba/a-pascoa-chegou-na-planet-chokolate!-50-off-para-1-caixa-com-16-bombons-recheados--1-pao-de-mel-recheado-ou-1-caixa-com-16-trufas-recheadas--1-pao-de-mel-recheado-de-rs-47.10-por-rs-23.55

第一个网址很好,但重定向的网址长247个字符。除非models.fields.URLField的{​​{1}}默认为 200 字符,否则此“不应该”成为问题。所以它验证失败,因为它太长了。

相反,请增加max_length,它应该有效:max_length有关可能的最长网址的信息see this SO question。它绝对超过200个字符。

编辑:设置Cookie时,它只会重定向到第二个网址!如果您使用现有Cookie重新访问同一页面,则只会显示较短的网址。


但小写网址呢?对于URL和小写版本,您的Web服务器似乎区分大小写:

http://www.nacolmeia.com.br/do/home/oferta/ener

...显示一般错误页面。它不会重定向到247个字符的URL。所以通过验证,因为models.URLField唯一关心的是;它是否加载网页?