- Author:
- stringify
- Posted:
- February 14, 2010
- Language:
- Python
- Version:
- 1.1
- Score:
- 0 (after 0 ratings)
This field is similar to the standard URLField, except it checks the given URL for a HTTP 301 response (permanent redirect) and updates its value accordingly.
For example:
>>> url = RedirectedURLField()
>>> url.clean('http://www.twitter.com/')
>>> 'http://twitter.com/'
In models:
class TestModel(models.Model):
url1 = RedirectedURLField('Redirected URL')
url2 = models.URLField('Standard URL')
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | # in util/models.py or wherever
import fields
from django.contrib.admin import options, widgets
from django.db.models.fields import CharField
class RedirectedURLField(CharField):
def __init__(self, verbose_name=None, name=None, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 200)
CharField.__init__(self, verbose_name, name, **kwargs)
def formfield(self, **kwargs):
defaults = {'form_class': fields.RedirectedURLField}
defaults.update(kwargs)
return super(RedirectedURLField, self).formfield(**defaults)
options.FORMFIELD_FOR_DBFIELD_DEFAULTS[RedirectedURLField] = {'widget': widgets.AdminURLFieldWidget}
# in util/fields.py or wherever
import urllib2
import urlparse
from django.forms.fields import url_re, RegexField, URL_VALIDATOR_USER_AGENT
from django.utils.translation import ugettext_lazy as _
class RedirectedURLField(RegexField):
default_error_messages = {
'invalid': _(u'Enter a valid URL.'),
'invalid_link': _(u'This URL appears to be a broken link.'),
}
# http://www.diveintopython.org/http_web_services/redirects.html
class RedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_301(self, req, fp, code, msg, headers):
result = urllib2.HTTPRedirectHandler.http_error_301(self, req,
fp, code, msg, headers)
result.status = code
return result
def __init__(self, max_length=None, min_length=None,
validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs):
super(RedirectedURLField, self).__init__(url_re, max_length, min_length,
*args, **kwargs)
self.user_agent = validator_user_agent
def clean(self, value):
# If no URL scheme given, assume http://
if value and '://' not in value:
value = u'http://%s' % value
# If no URL path given, assume /
if value and not urlparse.urlsplit(value)[2]:
value += '/'
value = super(RedirectedURLField, self).clean(value)
if value == u'':
return value
headers = {
"Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
"Accept-Language": "en-us,en;q=0.5",
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
"Connection": "close",
"User-Agent": self.user_agent,
}
opener = urllib2.build_opener(self.RedirectHandler())
try:
request = urllib2.Request(value, None, headers)
response = opener.open(request)
if 301 == getattr(response, 'status', None):
value = response.geturl()
except ValueError:
raise ValidationError(self.error_messages['invalid'])
except: # urllib2.URLError, httplib.InvalidURL, etc.
raise ValidationError(self.error_messages['invalid_link'])
return value
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Please login first before commenting.