web-dev-qa-db-fra.com

Obtention d'un paramètre de requête dans Jinja2

Comment puis-je récupérer un paramètre de requête a dans le modèle Jinja2?

http://foo.bar?a=1
36
Shankar Cabus

Je suis un peu en retard avec cette réponse, mais les autres solutions ne tiennent pas vraiment compte de votre utilisation de Flask.

Le fait que vous utilisez Flask avec Jinja2 rend votre situation un peu différente des autres frameworks. Flask met en fait à votre disposition des variables globales dans tous les Jinja2 modèles sans vous obliger à les transmettre explicitement au modèle.

Pour citer une partie de la documentation Flask sur http://flask.pocoo.org/docs/templating/#standard-context :

Les variables globales suivantes sont disponibles par défaut dans les modèles Jinja2:

...

request L'objet de requête actuel (flask.request)

...

Ainsi, par exemple, pour afficher le paramètre de demande "a" dans le modèle:

{{ request.args.get('a') }}

Le lien de documentation répertorie également les autres variables globales auxquelles vous pouvez accéder de manière similaire.

61
Kalle

Si vous utilisez webapp2 ...

Les paramètres de requête peuvent être récupérés facilement si vous utilisez webapp2.request comme un dictionnaire.

webapp2.request.get('[parameter]', '[optionalDefaultValue]')

Pour appliquer votre exemple (http://foo.bar?a=1&b=2&c=true):

a = webapp2.request.get('a') # a = 1
b = webapp2.request.get('b') # b = 2
c = webapp2.request.get('c') # c = true, may need further parsing to make it bool

Si vous voulez juste que la chaîne de requête non analysée appelle simplement:

qstring = webapp2.request.query_string 
# qstring = '?a=1&b=2&c=true

Une fois que vous avez collecté vos variables, passez-les simplement dans la méthode jinja2.render_template () comme vous le feriez pour n'importe quoi d'autre.

Ce n'est vraiment pas beaucoup plus facile que ça.

Mise à jour:

J'ai une façon assez unique de gérer les paramètres mais je vais essayer d'expliquer la version simple.

En supposant la chaîne de requête suivante

http://foo.bar?a=1&b=2&c=true

Voici comment j'écrirais le gestionnaire GET:

class BaseHandler(webapp2.RequestHandler): 
  def jinja2(self):
    return jinja2.get_jinja2(app=self.app)

  def render_template(self, template, **context):
    self.response.write(self.jinja2.render_template(template, **context))

  def get(self, **params):
    context = {}    
    context['a'] = webapp2.request.get('a')
    context['b'] = webapp2.request.get('b')
    context['c'] = webapp2.request.get('c')
    self.render_template([template], **context)

Donc, l'implémentation que j'utilise est un peu différente. J'empile également sur un paramètre _defaults qui est transmis via le routeur, et un paramètre _meta (c'est-à-dire title/description/url) qui est créé en faisant une recherche d'URI sur une structure d'URL personnalisée.

Dans mon gestionnaire de base, j'ai configuré jinja et encapsulé l'instance dans une méthode plus facile à appeler (c'est-à-dire render_template). Je n'ai pas eu cette idée, je pense que je l'ai eue des documents de webapp2 mais je m'écarte.

La partie importante est le paramètre "contexte". C'est là que vous empilez toutes les données que vous souhaitez envoyer au modèle. Désormais, toute valeur disponible dans cet objet sera désormais disponible dans le modèle.

Par exemple, vous pouvez imprimer la valeur de 'a' en utilisant:

{{ a }}

Si vous transmettez un tableau de valeurs comme l'un des paramètres, vous pouvez également les énumérer et appeler directement des propriétés spécifiques à l'aide de la notation par points.

La façon dont vos gestionnaires sont structurés dépend entièrement de vous. Contrairement à de nombreux frameworks, GAE offre beaucoup de flexibilité à cet égard. La façon dont je le fais implique beaucoup d'héritage donc je n'ai pas à répéter beaucoup. C'est un peu difficile à expliquer plus en détail sans coller tout mon handlers.py mais c'est l'essentiel de mon gestionnaire de base dont tous les autres de mes gestionnaires héritent. La seule différence notable est que je définis le contexte comme self.context afin que les classes enfants puissent y accéder. Cela semble assez compliqué dans le code, mais une fois que tout est câblé, il est presque sans effort d'ajouter des pages/routes supplémentaires.

3
Evan Plaice

Vous devrez transmettre ces informations à vos modèles jinja2, car il s'agit simplement d'un moteur de création de modèles et non du cadre Web.

La partie "génération de vues" de votre infrastructure Web qui traite les demandes reçoit généralement des informations d'en-tête de demande HTTP ou une structure de données. cela inclut souvent les paramètres de demande. Si c'est le cas, vous pouvez simplement le transmettre à votre modèle.

Même si les informations d'en-tête que vous obtenez n'incluent pas les paramètres de demande, elles incluront toujours l'URL. Une fois que vous avez l'URL dans votre code de fonction d'affichage, vous pouvez faire quelque chose comme ceci:

url = "http://foo.bar?a=1&b=2&c=true" # actually get this from your http request header
import urlparse
split_result = urlparse.urlsplit(url)
request_params = dict(urlparse.parse_qsl(split_result.query))
# request_params = {'a': '1', 'b': '2', 'c': 'true'}

Ensuite, vous pouvez envoyer ce request_params dictionnaire à votre modèle jinja.

0
Preet Kukreti