Ticket #1192: django_urlresolve_patch.diff

File django_urlresolve_patch.diff, 8.6 KB (added by django@…, 10 years ago)

patch v1

  • conf/global_settings.py

     
    130130# Whether to prepend the "www." subdomain to URLs that don't have it.
    131131PREPEND_WWW = False
    132132
     133# class that will resolve the url
     134URL_RESOLVER = 'django.core.urlresolvers.URLResolver'
     135
    133136# List of compiled regular expression objects representing User-Agent strings
    134137# that are not allowed to visit any page, systemwide. Use this for bad
    135138# robots/crawlers. Here are a few examples:
  • core/urlresolvers.py

     
    88"""
    99
    1010from django.core.exceptions import Http404, ImproperlyConfigured, ViewDoesNotExist
    11 import re
     11import re, types
    1212
    1313class Resolver404(Http404):
    1414    pass
     
    5858            raise ViewDoesNotExist, "Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e))
    5959
    6060class RegexURLResolver(object):
    61     def __init__(self, regex, urlconf_name):
     61    def __init__(self, regex, url_patterns):
    6262        # regex is a string representing a regular expression.
    63         # urlconf_name is a string representing the module containing urlconfs.
     63        # urlconf_name is a string representing the module containing urlconfs, or
     64        # a tupple with parsed urlpatterns
    6465        self.regex = re.compile(regex)
    65         self.urlconf_name = urlconf_name
     66        if isinstance(url_patterns, types.StringTypes):
     67            self.urlconf_name = url_patterns
     68        else:
     69            self._url_patterns = url_patterns
     70           
    6671
    6772    def resolve(self, path):
    6873        tried = []
    6974        match = self.regex.search(path)
    7075        if match:
    7176            new_path = path[match.end():]
    72             for pattern in self.urlconf_module.urlpatterns:
     77            for pattern in self.url_patterns:
    7378                try:
    7479                    sub_match = pattern.resolve(new_path)
    7580                except Resolver404, e:
     
    8691        except AttributeError:
    8792            try:
    8893                self._urlconf_module = __import__(self.urlconf_name, '', '', [''])
    89             except ValueError, e:
     94            except (ValueError, ImportError), e:
    9095                # Invalid urlconf_name, such as "foo.bar." (note trailing period)
    9196                raise ImproperlyConfigured, "Error while importing URLconf %r: %s" % (self.urlconf_name, e)
    9297            return self._urlconf_module
    9398    urlconf_module = property(_get_urlconf_module)
    9499
    95100    def _get_url_patterns(self):
    96         return self.urlconf_module.urlpatterns
     101        try:
     102            return self._url_patterns
     103        except AttributeError:
     104            self._url_patterns = self.urlconf_module.urlpatterns
     105            return self._url_patterns
    97106    url_patterns = property(_get_url_patterns)
    98107
    99108    def _resolve_special(self, view_type):
     
    109118
    110119    def resolve500(self):
    111120        return self._resolve_special('500')
     121       
     122class URLResolver(RegexURLResolver):
     123    def __init__(self, request, urlconf_name):
     124        RegexURLResolver.__init__(self, r'^/', urlconf_name)
     125
     126class HostURLResolver(RegexURLResolver):
     127    """
     128    The HostURLResolver resolves paths like URLResolver, but only on matching hostnames.
     129    Note: The urlpatterns have a different layout.
     130
     131    urlpatterns = (
     132    (r'^localhost$', patterns('',
     133         (r'^admin/', include('django.contrib.admin.urls.admin')),
     134        ),
     135    ),
     136    # default view, matches always, even when no HTTP_HOST is sent (HTTP 1.0)
     137    (r'', patterns('',
     138        ...
     139        ),
     140    ),
     141    )
     142    """
     143   
     144    def __init__(self, request, urlconf_name):
     145        self.request = request
     146        self.urlconf_name = urlconf_name
     147   
     148    def resolve(self, path):
     149        host = self.request.META.get('HTTP_HOST')
     150        # if IGNORE_HOST_PORT is true, we remove the port from
     151        # HTTP_POST and match only the hostname
     152        try:
     153            if self.urlconf_module.IGNORE_HOST_PORT:
     154                host = host[:host.rfind(":")]
     155        except: pass
     156        tried = []
     157        for thost, patterns in self.urlconf_module.urlpatterns:
     158            # HTTP 1.0 doesn't send a HTTP_HOST so we  can only match  the default
     159            # host which is defined as a empty string
     160            if thost != "":
     161                if host == None:
     162                    continue
     163                if not re.match(thost, host):
     164                    tried.append((thost,  None))
     165                    continue
     166            try:
     167                r = RegexURLResolver(r'^/', patterns)
     168                return r.resolve(path)
     169            except Resolver404, e:
     170                tried.append((host, e.args[0]['tried']))
     171               
     172        raise Resolver404, {'tried': tried, 'host':host}   
     173    urlconf_module = property(RegexURLResolver._get_urlconf_module)
  • core/handlers/base.py

     
    5151        "Returns an HttpResponse object for the given HttpRequest"
    5252        from django.core import exceptions, urlresolvers
    5353        from django.core.mail import mail_admins
    54         from django.conf.settings import DEBUG, INTERNAL_IPS, ROOT_URLCONF
     54        from django.conf.settings import DEBUG, INTERNAL_IPS, ROOT_URLCONF, URL_RESOLVER
    5555
    5656        # Apply request middleware
    5757        for middleware_method in self._request_middleware:
    5858            response = middleware_method(request)
    5959            if response:
    6060                return response
    61 
    62         resolver = urlresolvers.RegexURLResolver(r'^/', ROOT_URLCONF)
    6361        try:
     62            dot = URL_RESOLVER.rindex('.')
     63        except ValueError:
     64            raise exceptions.ImproperlyConfigured, '%s isn\'t a resolver module' % URL_RESOLVER
     65        ur_module, ur_classname = URL_RESOLVER[:dot], URL_RESOLVER[dot+1:]
     66        try:
     67            mod = __import__(ur_module, '', '', [''])
     68        except ImportError, e:
     69            raise exceptions.ImproperlyConfigured, 'Error importing urlresolver module %s: "%s"' % (ur_module, e)
     70        try:
     71                ur_class = getattr(mod, ur_classname)
     72        except AttributeError:
     73            raise exceptions.ImproperlyConfigured, 'Urlresolver module "%s" does not define a "%s" class' % (mw_module, mw_classname)
     74       
     75        resolver = ur_class(request, ROOT_URLCONF)
     76       
     77        try:
    6478            callback, callback_args, callback_kwargs = resolver.resolve(path)
    6579
    6680            # Apply view middleware
  • views/debug.py

     
    135135        if not tried:
    136136            # tried exists but is an empty list. The URLconf must've been empty.
    137137            return empty_urlconf(request)
    138 
     138    try:
     139        host = exception.args[0]['host']
     140    except:
     141        host = False
     142           
    139143    t = Template(TECHNICAL_404_TEMPLATE)
    140144    c = Context({
    141145        'root_urlconf': settings.ROOT_URLCONF,
    142146        'urlpatterns': tried,
     147        'host': host,
    143148        'reason': str(exception),
    144149        'request': request,
    145150        'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http",
     
    547552    {% if urlpatterns %}
    548553      <p>
    549554      Using the URLconf defined in <code>{{ settings.ROOT_URLCONF }}</code>,
     555      {% if host %}
     556      Django tried these URL patterns with hostname <code>{{ host|escape }}</code>, in this order:
     557      {% else %}
    550558      Django tried these URL patterns, in this order:
     559      {% endif %}
    551560      </p>
    552561      <ol>
    553         {% for pattern in urlpatterns %}
    554           <li>{{ pattern|escape }}</li>
    555         {% endfor %}
     562        {% if host %}
     563            {% for pattern in urlpatterns %}
     564                <li>{{ pattern.0|escape }}<br/>
     565                {% if pattern.1 %}
     566                    <ol>
     567                    {% for match in pattern.1 %}
     568                        <li>{{ match|escape}}</li>
     569                    {% endfor %}
     570                    </ol>
     571                  {% else %}
     572                  Hostname didn't match, or empty url pattern
     573                  {% endif %}
     574                  </li>
     575            {% endfor %}
     576        {% else %}
     577            {% for pattern in urlpatterns %}
     578              <li>{{ pattern|escape }}</li>
     579            {% endfor %}
     580        {% endif %}
    556581      </ol>
    557582      <p>The current URL, <code>{{ request.path }}</code>, didn't match any of these.</p>
    558583    {% else %}
Back to Top