代码之家  ›  专栏  ›  技术社区  ›  Chase Seibert

如何使用django url名称空间?

  •  29
  • Chase Seibert  · 技术社区  · 15 年前

    我想知道 Django URL namespaces . 但我找不到任何例子或文档。

    这是我试过的。

    网址.py:

    from django.conf.urls.defaults import *
    
    urlpatterns = patterns('',
        (r'^foo/', include('sub_urls', namespace='foo', app_name='foo')),
        (r'^bar/', include('sub_urls', namespace='bar', app_name='bar')),            
    )
    

    亚:

    from django.conf.urls.defaults import patterns, url
    from views import view1
    
    urlpatterns = patterns('views',
        url(r'^(?P<view_id>\d+)/$', view1, name='view1')
    )
    

    查看:

    from django.shortcuts import render_to_response
    
    def view1(request, view_id):
        return render_to_response('view1.html', locals())
    

    在view1.html中,%url foo:view1 3%outputs/foo/3,%url bar:view1 3%outputs/bar/3。无论我浏览到/foo/x还是/bar/x,这都是正确的。

    我想要的是能够浏览到/foo/x或/bar/x,并分别输出%url view1 3%/foo/3或/bar/3。

    4 回复  |  直到 11 年前
        1
  •  3
  •   Mystic    15 年前

    我想这在德姜哥是不可能的。看看这个 message board post 哪些参考文献 Ticket 11559 . 我认为您正在尝试做同样的事情——有效地将一个隐式参数传递给URL标记。

    另外,假设 sub_urls 来自同一个应用程序,两次都应确保 app_name 在这两种情况下是相同的。您只需要更改名称空间。

        2
  •  6
  •   Torsten Engelbrecht    11 年前

    似乎没有直接的方法。我会使用一个类似的解决方案,正如您使用模板标记介绍的那样,尽管我发现了一种更通用的方法。我使用了这样一个事实:您可以在URL配置中传递可选参数,以便跟踪命名空间:

    #urls.py
    from django.conf.urls import defaults
    
    urlpatterns = defaults.patterns('',
        defaults.url(r'^foo/', include('sub_urls', namespace='foo', app_name='myapp'), 
        kwargs={'namespace':'foo'}),
        defaults.url(r'^bar/', include('sub_urls', namespace='bar', app_name='myapp'),
        kwargs={'namespace':'bar'}),      
    )
    

    这也违反了干燥原则,但也不多见。

    然后在您的视图中,您会得到名称空间变量(sub_urls.py将是相同的):

    #views.py
    from django import shortcuts
    
    def myvew(request, namespace):
        context = dict(namespace=namespace)
        return shortcuts.render_to_response('mytemplate.html', context)
    

    稍后,您只需要一个简单的标记,将名称空间变量和视图名称传递给:

    #tags.py
    from django import template
    from django.core import urlresolvers
    
    register = template.Library()
    
    def namespace_url(namespace, view_name):
       return urlresolvers.reverse('%s:%s' % (namespace, view_name, args=args, kwargs=kwargs)))
    register.simple_tag(namespace_url)
    

    并在模板中使用它(确保将视图名称作为字符串传递,而不是作为模板变量传递):

    <!-- mytemplate.html -->
    {% load tags %}
    {% namespace_url namespace "view1"%}
    

    谢谢你的提示。我在找这样的东西。

        3
  •  0
  •   Chase Seibert    15 年前

    这是我想出的一个解决方案。

    查看:

    from django.shortcuts import render_to_response
    from django.template import RequestContext
    
    def render_response_context(view, locals):
        request = locals["request"]
        app = "bar" if request.META["PATH_INFO"].lower().startswith("/bar") else "foo"
        return render_to_response(view, locals, 
            context_instance=RequestContext(request, current_app=app))
    
    def view1(request, view_id):    
        return render_response_context('view1.html', locals())
    

    VIEW1.HTML:

    {% load extras %}
    {% namespace_url view1 3 %}
    

    PYS.PY:

    from django import template
    from django.core.urlresolvers import reverse
    
    register = template.Library()
    
    @register.tag
    def namespace_url(parser, token):
        tag_name, view_string, arg1 = token.split_contents()
        return NamespaceUrlNode(view_string, arg1)
    
    class NamespaceUrlNode(template.Node):
        def __init__(self, view_string, arg1):
            self.view_string = view_string
            self.arg1 = arg1
        def render(self, context):
            return reverse("%s:%s" % (context.current_app, self.view_string), args=[self.arg1])
    

    基本上,我确保总是将当前的_-app上下文作为“foo”或“bar”传递,我通过查看请求URL手动计算。然后我使用一个自定义标记,根据当前的_app解析一个URL。

    它不是很普通;“foo”和“bar”是硬编码的,并且标记只能接受一个参数。即使解决了这些问题,这看起来像是一次黑客攻击。

        4
  •  0
  •   Steven Potter    15 年前

    我意识到下面的解决方案违反了dry原则,因为您必须为foo和bar创建基本上重复的url配置文件,但是我认为它应该可以工作。

    ULLS.PY:

    from django.conf.urls.defaults import *
    
    urlpatterns = patterns('',
        (r'^foo/', include('sub_urls_foo')),
        (r'^bar/', include('sub_urls_bar')),            
    )
    

    子网址:

    from django.conf.urls.defaults import patterns, url
    from views import view1
    
    urlpatterns = patterns('views',
        url(r'^(?P<view_id>\d+)/$', view1, 'view1_foo', {'namespace': 'view1_foo'})
    )
    

    子网址\u bar.py:

    from django.conf.urls.defaults import patterns, url
    from views import view1
    
    urlpatterns = patterns('views',
        url(r'^(?P<view_id>\d+)/$', view1, 'view1_bar', {'namespace': 'view1_bar'})
    )
    

    查看:

    from django.shortcuts import render_to_response
    
    def view1(request, view_id, namespace):
        return render_to_response('view1.html', locals())
    

    然后,对于模板,使用以下命令:

    {% url namespace 3 %}
    

    我还没有测试过在%url%标记的name部分使用变量的想法,但我认为它应该有效。