2009-08-14 8 views
7

Ceci est une question très similaire à ce fil SO sur middleware and views communicatingmiddleware par rapport à processeur de contexte pour une vue navigation/affichage dépendant

Nous aimerions que nos modèles soient donnés un ensemble standard de variables de contexte. Ainsi, un processeur de contexte semble approprié, cependant, il ne semble pas que le processeur de contexte soit sensible à la vue. Nous avions auparavant été contraints d'inspecter la pile d'appels pour obtenir des informations contextuelles sur la vue qui faisait quoi.

C'est là que nous avons vu le thread middleware ainsi que la signature process_view() pour un middleware qui nous donne un aperçu de la vue.

Cela semblait plus proche de nos besoins, mais ne nous permettait pas de modifier la variable de contexte, pas plus que les autres méthodes de middleware. Donc, notre idée initiale était de modifier l'objet requête avec toutes les informations globales et contextuelles dont nous avions besoin pour nos modèles et de forcer les modèles à appeler depuis {{request.something}} pour les informations spécifiques dont nous avons besoin, comme {{request.viewname}}.

Ainsi, nos questions:

  • modifie les valeurs de réglage/objet sur la demande une chose acceptée à faire pour pousser des informations spécifiques de l'application contextuelle/globale de vos modèles? Ou la pratique standard est-elle toujours de le mettre en contexte?
  • Y a-t-il des moyens/astuces pour rendre la vue des processeurs de contexte consciente qui n'implique pas de la passer explicitement ou de faire une introspection de pile?
  • Est-ce que le middleware.process_response peut modifier le contexte ou est-il immuable?

Répondre

4

Il est parfaitement possible de définir des variables sur la requête dans le middleware - je le fais tout le temps.

Il n'y a aucun moyen d'utiliser process_response pour cela, car alors le modèle a déjà été rendu - à ce stade, tout ce que vous obtenez est un HttpResponse contenant un tas de HTML. Une alternative pourrait être d'envelopper render_to_response avec votre propre fonction, qui prend le contexte, avec la demande et le modèle, et le modifie si nécessaire avant de passer à la fonction de rendu réelle. Cela a l'avantage de modifier le contexte actuel, mais l'inconvénient est que vous devez vous souvenir de l'appeler dans chaque vue au lieu de la fonction par défaut.

+0

Voir aussi http://jboxer.com/2009/05/django-middleware-vs-context-processors/ – Ztyx

2

Vous pouvez le faire en utilisant un intergiciel et un processeur de contexte en tandem. Le middleware connaît la vue et peut définir un attribut sur la demande. Ensuite, le processeur de contexte peut déplacer tout ce qui est défini dans la requête dans le contexte.

Par exemple:

class ExtraContextMiddleware(object): 
    """ 
    Adds extra context to the response for certain views. 

    Works in tandem with the extra_context context processor. 
    """ 

    context_map = { 
     #Adds the supplied context dict to the named views 
     'my_view_name': {'foo': 'Hello', 'bar': 'Goodbye'}, 
    } 

    def process_view(self, request, view, *args, **kwargs): 
     try: 
      request.extra_context = self.context_map[view.func_name] 
     except KeyError: 
      pass 

Ensuite, le processeur de contexte:

def extra_context(request): 
    """Context processor for adding extra context. 
    Works in tandem with ExtraContextMiddleware.""" 
    try: 
     return request.extra_context 
    except AttributeError: 
     return {} 
Questions connexes