Reputation: 3056
Could someone please clarify me why this url http://www.nacolmeia.com.br/do/Home/oferta/EnER
is not being accepted in a form generated from URLField's Django?
:)
Thanks
Upvotes: 7
Views: 11909
Reputation: 12638
I think I found the issue. When you open this URL:
http://www.nacolmeia.com.br/do/Home/oferta/EnER
...it re-directs to this URL:
The first URL is fine, but the re-directed one is 247 characters long. This "shouldn't" be a problem, except that models.fields.URLField
has max_length
which defaults to 200 characters. So it fails validation because it's too long.
Instead, increase the max_length
and it should work: models.URLField(max_length=255)
For info on the longest URL possible, see this SO question. It's definitely longer than 200 characters though.
EDIT: It only re-directs to the second URL when setting a cookie! If you re-visit the same page again with an existing cookie, it just displays the shorter URL.
But what about the lowercase URL? It appears your web-server is case-sensitive regarding URLs, and the lowercase version:
http://www.nacolmeia.com.br/do/home/oferta/ener
...displays a generic error page. It doesn't re-direct to the 247 character URL. So that passes validation since the only thing models.URLField cares about is; does it load a webpage or not?
Upvotes: 0
Reputation: 39297
Are you hosting the site from the same server you are trying to validate it on? docs
Note that when you're using the single-threaded development server, validating a URL being served by the same server will hang. This should not be a problem for multithreaded servers.
It doesn't look like its failing validation at the form level
>>> 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.']
>>>
If you don't need to validate that the website doesn't return a 404, in your models.py
url = models.URLField(verify_exists=False)
edit:
after some digging around in the django source code here
and some messing around with the shell, I'm still not sure why the URL with caps is causing a redirect loop.
>>> 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')
>>>
The actual exception being raised is an 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
>>>
here are some posts talking about the HTTPError: here
and here
seems like it has something to do with cookies, but I'm not able to offer a good explanation, I'll leave that to some one else.
A workaround that might work if you don't want to turn off validation but don't care about the capitalization of your urls is to override the clean_field method of your forms.
def clean_your_url_field(self):
return self.cleaned_data['your_url_field'].lower()
Upvotes: 8