from django.forms import fields, TextInput from oscar.core import validators class ExtendedURLField(fields.URLField): """ Custom field similar to URLField type field, however also accepting and validating local relative URLs, ie. '/product/' """ default_validators = [] # Django 1.6 renders URLInput as , which causes some # browsers to require the input to be a valid absolute URL. As relative # URLS are allowed for ExtendedURLField, we must set it to TextInput widget = TextInput def __init__(self, max_length=None, min_length=None, verify_exists=None, *args, **kwargs): # We don't pass on verify_exists as it has been deprecated in Django # 1.4 super(fields.URLField, self).__init__( max_length, min_length, *args, **kwargs) # Even though it is deprecated, we still pass on 'verify_exists' as # Oscar's ExtendedURLValidator uses it to determine whether to test # local URLs. if verify_exists is not None: validator = validators.ExtendedURLValidator( verify_exists=verify_exists) else: validator = validators.ExtendedURLValidator() self.validators.append(validator) def to_python(self, value): # We need to avoid having 'http' inserted at the start of # every value so that local URLs are valid. if value and value.startswith('/'): return value return super(ExtendedURLField, self).to_python(value)