Django cross-site reverse URLs

前端 未结 4 471
天命终不由人
天命终不由人 2021-02-01 10:41

Probably simple question and I\'m just missing something, but I\'m stuck out of ideas.

I have Django project serving several sites with distinct sessions.py

相关标签:
4条回答
  • 2021-02-01 10:58

    Yes, you'd need to make your own {% url %} tag which uses it's own reversal method.

    For example, to reverse specifically against the site_a urlconf then you could use a method like this:

    from django.core.urlresolvers import reverse
    import site_a
    
    def site_a_reverse(viewname, args=None, kwargs=None):
        # If your sites share the same database, you could get prefix from Site.objects.get(pk=site_a.settings.SITE_ID)
        prefix = 'http://a.example.com/'  # Note, you need the trailing slash
        reverse(viewname, urlconf=site_a.urls, args=args, kwargs=kwargs, prefix=prefix)
    
    0 讨论(0)
  • 2021-02-01 11:01

    I've implemented it by overriding django.core.urlresolvers.reverse with my custom function:

    from django.core import urlresolvers
    from django.conf import settings
    
    __real_reverse = urlresolvers.reverse
    
    def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None):
        try:
            return __real_reverse(viewname, urlconf, args, kwargs, prefix)
        except urlresolvers.NoReverseMatch, no_match:
            external_urlconfs = getattr(settings, 'EXTERNAL_URLCONFS', [])
            for p, c in external_urlconfs:
                c = urlresolvers.RegexURLResolver(r'^/', c)
                try:
                    return p + c.reverse(viewname, *args, **kwargs)
                except urlresolvers.NoReverseMatch:
                    pass
            raise no_match
    
    urlresolvers.reverse = reverse
    

    Then listing URLconfs in settings.py like this:

    ROOT_URLCONF = 'project.urls_a'
    
    EXTERNAL_URLCONFS = (
        ('http://b.example.com/', 'project.urls_b'),
    )
    
    0 讨论(0)
  • 2021-02-01 11:05

    Reverse overwrite for Django 1.7.x using the same settings from @drdaeman

    # -*- coding: utf-8 -*-
    from django.core import urlresolvers
    from django.conf import settings
    
    __real_reverse = urlresolvers.reverse
    
    
    def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current_app=None):
        try:
            return __real_reverse(viewname, urlconf, args, kwargs, prefix, current_app)
        except urlresolvers.NoReverseMatch, no_match:
            external_urlconfs = getattr(settings, 'EXTERNAL_URLCONFS', [])
            for p, c in external_urlconfs:
                urlconf = c
                try:
                    return p + __real_reverse(viewname, urlconf, args, kwargs, prefix, current_app)
                except urlresolvers.NoReverseMatch:
                    pass
            raise no_match
    
    urlresolvers.reverse = reverse
    

    I placed the code in the urls.py file to execute at startup

    0 讨论(0)
  • 2021-02-01 11:21

    I would suggest making two changes. (1) Move templates to a common directory (rather than per-application) if you already haven't. (2) Investigate the newly added URL namespaces feature.

    The first change will allow you to have a common base template and selectively override it for various apps/sites. The second might serve to make your URLs "drier".

    0 讨论(0)
提交回复
热议问题