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 django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
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.

Reply via email to