web-dev-qa-db-ja.com

Django URL名前空間をどのように使用しますか?

Django URL名前空間 のコツをつかもうとしています。しかし、例やドキュメントが見つかりません。

これが私が試したことです。

urls.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')),            
)

sub_urls.py:

from Django.conf.urls.defaults import patterns, url
from views import view1

urlpatterns = patterns('views',
    url(r'^(?P<view_id>\d+)/$', view1, name='view1')
)

views.py:

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%}は/ foo/3を出力し、{%url bar:view1 3%}は/ bar/3を出力します。これは、/ foo/Xまたは/ bar/Xのどちらを参照する場合にも当てはまります。

私が欲しいのは、/ foo/Xまたは/ bar/Xを参照し、{%url view1 3%}がそれぞれ/ foo/3または/ bar/3を出力できるようにすることです。

29
Chase Seibert

これは現在Djangoでは不可能だと思います。これを見てください 掲示板の投稿 これは チケット11559 を参照しています。I同じことをしようとしていると考えてください-暗黙のパラメータをURLタグに効果的に渡します。

また、sub_urlsはどちらの場合も同じアプリからのものであり、app_nameはどちらの場合も同じです。名前空間を変更するだけで済みます。

3
Mystic

それを行う直接的な方法はないようです。より一般的な方法を見つけましたが、テンプレートタグを使用して紹介したのと同様のソリューションを使用します。 url confでオプションのパラメーターを渡すことができるという事実を利用したので、名前空間を追跡できます。

#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'}),      
)

これもDRYの原則に違反しますが、それほど多くはありません:)

次に、ビューで名前空間変数を取得します(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"%}

ところであなたのヒントをありがとう..私はsthを探していました。このような。

6

これが私が思いついた解決策の1つです。

views.py:

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 %}

extras.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])

基本的に、current_appコンテキストを常に「foo」または「bar」として渡すようにしました。これは、リクエストURLを見て手動で計算します。次に、current_appに基づいてURLを解決するカスタムタグを使用します。

あまり一般的ではありません。 「foo」と「bar」はハードコーディングされており、タグは1つの引数しか取ることができません。これらの問題が修正されたとしても、これはハックのようです。

0
Chase Seibert

以下の解決策は、fooとbarに対して本質的に重複するURL構成ファイルを作成する必要があるため、DRYプリンシパルに違反していることに気付きましたが、機能するはずです。

urls.py:

from Django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^foo/', include('sub_urls_foo')),
    (r'^bar/', include('sub_urls_bar')),            
)

sub_urls_foo.py:

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'})
)

sub_urls_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'})
)

views.py:

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セクションで変数を使用するというアイデアはテストしていませんが、機能するはずです。

0
Steven Potter