Marten,
Using your *dispatcher_api* branch, I found a few issues - I believe this
is an acceptable place to post them. My apologies if this is not the case.
My use case is this: Using a single Django codebase, I plan to have
www.example.com and my.example.com. 'my' will be https, while 'www' will be
http. 'my' will be for logged in actions (including signup/logging in), and
'www' will be largely anonymous usage and cached using various mechanisms.
I've figured out how to do scheme and host based constraints easily enough,
thanks to a code sample you provided to me. This is what I've developed it
into, and it works pretty well (once I got around the *Major* issue listed
below):
from django.conf.urls import url, include
from django.core.urls import Constraint, Resolver404
class ConstraintBase(Constraint):
"""
This exists purely as a way to ensure MRO mixin inheritance will work
"""
def match(self, path, request=None):
return path, (), {}
def construct(self, url, *args, **kwargs):
return url, args, kwargs
class SchemeConstraintMixin(object):
scheme = ''
def match(self, path, request=None):
if request and request.scheme == self.scheme:
return super(SchemeConstraintMixin, self).match(path, request)
raise Resolver404()
def construct(self, url, *args, **kwargs):
url.scheme = self.scheme
return super(SchemeConstraintMixin, self).construct(url, *args,
**kwargs)
class HostConstraintMixin(object):
host = ''
def match(self, path, request=None):
if request and request.get_host() == self.host:
return super(HostConstraintMixin, self).match(path, request)
raise Resolver404()
def construct(self, url, *args, **kwargs):
url.host = self.host
return super(HostConstraintMixin, self).construct(url, *args,
**kwargs)
class SchemeHostConstraint(SchemeConstraintMixin, HostConstraintMixin,
ConstraintBase):
def __init__(self, scheme, host):
self.scheme = scheme
self.host = host
www_constraint = SchemeHostConstraint('http', 'localhost:8000')
my_constraint = SchemeHostConstraint('https', 'my.example.com')
urlpatterns = [
url(www_constraint, include([
url(r'^$', 'testviews.views.testview', {'template':
'testview1.html'}, 'testview1'),
url(r'^test2/$', 'testviews.views.testview', {'template':
'testview2.html'}, 'testview2')
])),
url(my_constraint, include([
url(r'^test3/$', 'testviews.views.testview', {'template':
'testview3.html'}, 'testview3'),
url(r'^test4/$', 'testviews.views.testview', {'template':
'testview3.html'}, 'testview4')
]))
]
The view simply renders a template. The templates simply display the `{%
url %}` output of the available url patterns mentioned above. With that
preamble done, I'll mention my findings below:
*Major bug:* the `request` object needs to be passed into `resolve()` here:
https://github.com/knbk/django/blob/4a9d2a05bb76c9ad996921b9efadd8dad877540e/django/core/handlers/base.py#L134
- otherwise host and scheme constraints cannot work. I believe there are
other instances of `resolve()` not getting `request`, but mostly in tests.
Is there a way for `request` to be a required parameter instead of
defaulting to `None`?
*Minor bug:* Given two subdomains, my.example.com and localhost:8000, going
to a url using the 'localhost:8000' subdomain that only exists on the 'my'
subdomain (ie. http://my.example.com/test3/ exists, but you try to go
to http://localhost:8000/test3/), the debug mode 'patterns tried list' is a
series of blank lines. See image below:
<https://lh3.googleusercontent.com/-jZ-DOLwDKdg/VZ3rvjNSuFI/AAAAAAAACds/UdeLtKNyi8Y/s1600/Screen%2BShot%2B2015-07-07%2Bat%2B9.05.13%2BPM.png>
*Nice to have:* When attempting to use multiple constraints (ie. list or
tuple of constraints), using `RegexPattern` seems to be required when doing
pattern matching - otherwise it messes up while calling `construct`. First
glance says this is by design? I think it would be nice to still be able to
use the old r'<regex here>' (without wrapping in `RegexPattern`) syntax as
well. Not critical, as the multi-constraints is NOT breaking behaviour,
just new.
*Nice to have:* I realise this isn't likely to happen at all, but it would
be nice if when `reverse()` and `{% url %}` are called, it would be good to
be able to automatically drop the scheme and host when reconstituting an
absolute URL if the scheme and host of the current request match. However,
I'm pretty sure that this is not possible, given the various scenarios in
which these methods can be called. Obviously, this is not required, as the
resulting URL (with scheme/host or without when matching) will still work
regardless!
I hope this was clear. If there is a way I can be of more assistance,
please let me know! Nice work, by the way. I'm stoked to have this in 1.9.
James
--
You received this message because you are subscribed to the Google Groups
"Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/7d8ac977-b8f1-4624-9d3f-42dc299ea136%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.