Question

Probablement une question simple et je manque juste quelque chose, mais je suis coincé sur des idées.

J'ai un projet Django desservant plusieurs sites avec des sessions.py distincts et des ROOT_URLCONF complètement différents. Un site gère l'enregistrement des utilisateurs, l'authentification et les paramètres de profil, un autre site (sur un autre domaine) fait office de gestionnaire de fichiers, etc. Les sites partagent les mêmes bases de données, supports et modèles. Tous les sites partagent la même base d'utilisateurs et implémentent une sorte de mécanisme transparent de signature unique / signature unique. C'est comme un grand site, couvrant plusieurs domaines.

Le problème est que j'ai beaucoup de balises {% url%} dans mes modèles, et elles ne fonctionnent pas lorsque les modèles sont utilisés sur d'autres sites. Et j'aimerais éviter autant que possible de coder en dur les URL.

Par exemple, sur le site A (a.exemple.org), j'ai un

url('^users/

entrée dans A URLconf. Ensuite, dans un modèle global_menu.html , j'ai {% url list_users%} et cela fonctionne parfaitement, ce qui entraîne "& <; code> / utilisateurs / ".

Maintenant, il y a le site B (b.exemple.org), partageant de nombreux éléments internes avec A. Pour avoir une apparence commune, je souhaite utiliser le même global_menu.html sur le site. B et souhaitez que {% url list_users%} affiche "& <; code> http://a.example.org/users/ ". Quel est le meilleur moyen d’atteindre cet objectif?

Actuellement, j'utilise un global_menu.html distinct pour chaque site, mais cela contrevient au principe de DRY et n'est pas très pratique. Et, oui, j'utilise le framework contrib.sites de Django avec des ID de SITE distincts définis dans settings.py pour chaque site, mais pas encore. en train de l'utiliser nulle part ailleurs.

Mettre à jour : je pense actuellement à réimplémenter la balise url ou à appliquer un correctif à la clé de singe reverse () , pour appeler l'original, et sur les exceptions, effectue une recherche supplémentaire dans certaines "listes d'URI étrangères". S'il existe déjà quelque chose comme cela, je serais heureux de l'entendre.

Merci d’avance pour vos réponses!

, 'example.accounts.list_users', name='list_users'),

entrée dans A URLconf. Ensuite, dans un modèle global_menu.html , j'ai {% url list_users%} et cela fonctionne parfaitement, ce qui entraîne "& <; code> / utilisateurs / ".

Maintenant, il y a le site B (b.exemple.org), partageant de nombreux éléments internes avec A. Pour avoir une apparence commune, je souhaite utiliser le même global_menu.html sur le site. B et souhaitez que {% url list_users%} affiche "& <; code> http://a.example.org/users/ ". Quel est le meilleur moyen d’atteindre cet objectif?

Actuellement, j'utilise un global_menu.html distinct pour chaque site, mais cela contrevient au principe de DRY et n'est pas très pratique. Et, oui, j'utilise le framework contrib.sites de Django avec des ID de SITE distincts définis dans settings.py pour chaque site, mais pas encore. en train de l'utiliser nulle part ailleurs.

Mettre à jour : je pense actuellement à réimplémenter la balise url ou à appliquer un correctif à la clé de singe reverse () , pour appeler l'original, et sur les exceptions, effectue une recherche supplémentaire dans certaines "listes d'URI étrangères". S'il existe déjà quelque chose comme cela, je serais heureux de l'entendre.

Merci d’avance pour vos réponses!

Était-ce utile?

La solution

Je l'ai implémenté en remplaçant django.core.urlresolvers.reverse par ma fonction personnalisée:

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

Ensuite, répertoriez les URLconfs dans settings.py comme ceci:

ROOT_URLCONF = 'project.urls_a'

EXTERNAL_URLCONFS = (
    ('http://b.example.com/', 'project.urls_b'),
)

Autres conseils

Oui, vous devez créer votre propre balise {% url%} qui utilise sa propre méthode d'inversion.

Par exemple, pour inverser spécifiquement le paramètre site_a urlconf, vous pouvez utiliser une méthode comme celle-ci:

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)

Écraser en sens inverse pour Django 1.7.x en utilisant les mêmes paramètres que @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

J'ai placé le code dans le fichier urls.py à exécuter au démarrage

Je suggérerais de faire deux changements. (1) Déplacez les modèles dans un répertoire commun (plutôt que par application) si ce n'est déjà fait. (2) Recherchez l'URL nouvellement ajoutée espaces de noms . fonctionnalité.

La première modification vous permettra d’avoir un modèle de base commun et de le remplacer de manière sélective pour diverses applications / sites. La seconde pourrait servir à rendre vos URL "plus sèches".

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top