9

おそらく単純な質問で、何かが足りないだけですが、アイデアがありません。

私は Django プロジェクトをいくつかのサイトに提供しsessions.py、まったく異なるROOT_URLCONFs を使用しています。1 つのサイトはユーザー登録、認証、およびプロファイル設定を処理し、別のサイト (別のドメイン上) はファイル マネージャーとして機能します。サイトは同じ DB、メディア、およびテンプレートを共有しています。すべてのサイトが同じユーザーベースを共有しており、一種の透過的なシングル サインオン/シングル サインオフ メカニズムを実装しています。これは、複数のドメインにまたがる 1 つの大きなサイトのようなものです。

問題は、テンプレートに多くの{% url %}タグがあり、テンプレートが他のサイトで使用されている場合に機能しないことです。また、URL のハードコーディングはできるだけ避けたいと考えています。

たとえば、サイト A (a.example.org) には

url('^users/$', 'example.accounts.list_users', name='list_users'),

A の URLconf のエントリ。次に、global_menu.html私が持っているいくつかのテンプレートで{% url list_users %}、明らかに完全に機能し、「/users/」になります。

現在、サイト B (b.example.org) があり、多くの内部構造を A と共有しています。共通のルック アンド フィールを持たせるために、global_menu.htmlサイト Bでも同じものを使用し、 {% url list_users %}" " を出力したいと考えていますhttp://a.example.org/users/。これを達成するための最良の方法は何ですか?

現在、私はglobal_menu.htmlサイトごとに別々に使用していますが、これは DRY の原則に反しており、あまり便利ではありません。そして、はい、私は Django のフレームワークを使用しており、サイトごとにcontrib.sites個別SITE_IDの が定義されていますが、実際には他の場所ではまだ使用していません。settings.py

更新url:現在、タグまたはモンキーパッチを再実装reverse()して、元のものを呼び出し、例外で「外部URIリスト」で追加のルックアップを実行することを考えています。このようなものが既に存在する場合 — 喜んで伺います。

回答ありがとうございます!

4

4 に答える 4

12

django.core.urlresolvers.reverseカスタム関数でオーバーライドして実装しました。

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

settings.py次に、次のように URLconf をリストします。

ROOT_URLCONF = 'project.urls_a'

EXTERNAL_URLCONFS = (
    ('http://b.example.com/', 'project.urls_b'),
)
于 2009-08-04T23:21:30.177 に答える
2

{% url %}はい、独自の反転メソッドを使用する独自のタグを作成する必要があります。

たとえば、site_a urlconfに対して具体的に逆にする場合は、次のような方法を使用できます。

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)
于 2009-08-04T21:08:42.847 に答える
2

@drdaeman からの同じ設定を使用して、Django 1.7.x の逆上書き

# -*- 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

起動時に実行するコードを urls.py ファイルに配置しました

于 2015-01-08T12:12:34.853 に答える
0

2 つの変更を行うことをお勧めします。(1) まだ行っていない場合は、テンプレートを (アプリケーションごとではなく) 共通のディレクトリに移動します。(2) 新しく追加された URL名前空間機能を調査します。

最初の変更により、共通の基本テンプレートを使用して、さまざまなアプリ/サイトに対して選択的にオーバーライドできるようになります。2 つ目は、URL を「ドライ」にするのに役立つ場合があります。

于 2009-08-03T16:53:42.573 に答える