2011-08-16 12 views
18

Come posso aggiungere gli url specifici del modello al modello. Diciamo che voglio creare un collegamento di modifica. Direi che usare la funzione uri_for() sarebbe un approccio facile.webapp2 + jinja2: Come posso ottenere uri_for() lavorando in jinja2-views

ma il seguente mi dà "UndefinedError: 'webapp2' è definito"

{% webapp2.uri_for("editGreeting", greeting.key().id()) %} 

o dovrei preparare questi nel MainPage-Request-Handler? Se è così, non so come aggiungerli ad ogni saluto.

il seguente codice-esempio è tratto da: http://webapp-improved.appspot.com/tutorials/gettingstarted/templates.html

Controller/Handler

class MainPage(webapp2.RequestHandler): 
    def get(self): 
     guestbook_name=self.request.get('guestbook_name') 
     greetings_query = Greeting.all().ancestor(
      guestbook_key(guestbook_name)).order('-date') 
     greetings = greetings_query.fetch(10) 

     if users.get_current_user(): 
      url = users.create_logout_url(self.request.uri) 
      url_linktext = 'Logout' 
     else: 
      url = users.create_login_url(self.request.uri) 
      url_linktext = 'Login' 

     template_values = { 
      'greetings': greetings, 
      'url': url, 
      'url_linktext': url_linktext, 
     } 

     path = os.path.join(os.path.dirname(__file__), 'index.html') 
     self.response.out.write(template.render(path, template_values)) 

Template/Vista:

<html> 
    <body> 
    {% for greeting in greetings %} 
     {% if greeting.author %} 
     <b>{{ greeting.author.nickname }}</b> wrote: 
     {% else %} 
     An anonymous person wrote: 
     {% endif %} 
     <blockquote>{{ greeting.content|escape }}</blockquote> 
    {% endfor %} 

    <form action="/sign" method="post"> 
     <div><textarea name="content" rows="3" cols="60"></textarea></div> 
     <div><input type="submit" value="Sign Guestbook"></div> 
    </form> 

    <a href="{{ url }}">{{ url_linktext }}</a> 
    </body> 
</html 

Il BaseHandler di classe è la classe tutti i gestori ereditano da . Ho provato quanto segue suggerito da @moraes. ho ancora:.

value = self.func(obj) 
File "C:\Users\timme04\python\hellowebapp\handlers\basehandler.py", line 23, in jinja2 
return jinja2.get_jinja2(factory=self.jinja2_factory) 
File "C:\Users\timme04\python\hellowebapp\webapp2_extras\jinja2.py", line 212, in get_jinja2 
jinja2 = app.registry[key] = factory(app) 
TypeError: jinja2_factory() takes exactly 1 argument (2 given) 

:(

import webapp2 

from webapp2_extras import jinja2 

class BaseHandler(webapp2.RequestHandler): 

    def jinja2_factory(app): 
     j = jinja2.Jinja2(app) 
     j.environment.filters.update({ 
      # Set filters. 
      # ... 
     }) 
     j.environment.globals.update({ 
      # Set global variables. 
      'uri_for': webapp2.uri_for, 
      # ... 
     }) 
     return j 

    @webapp2.cached_property 
    def jinja2(self): 
     # Returns a Jinja2 renderer cached in the app registry. 
     return jinja2.get_jinja2(factory=self.jinja2_factory) 

    def render_response(self, _template, **context): 
     # Renders a template and writes the result to the response. 
     rv = self.jinja2.render_template(_template, **context) 
     self.response.write(rv) 
+0

Sembra che l'esempio di codice potrebbe essere mancante 'importazione webapp2'. –

+0

Ho già aggiunto "import webapp2" al mio controller/gestore ma non posso ancora utilizzarlo nel mio modello ... – crushervx

risposta

26

È necessario impostare uri_for come una variabile globale Un modo per farlo è quello di impostare un inizializzatore per le variabili globali e filtri:

import webapp2 
from webapp2_extras import jinja2 

def jinja2_factory(app): 
    j = jinja2.Jinja2(app) 
    j.environment.filters.update({ 
     # Set filters. 
     # ... 
    }) 
    j.environment.globals.update({ 
     # Set global variables. 
     'uri_for': webapp2.uri_for, 
     # ... 
    }) 
    return j 

class BaseHandler(webapp2.RequestHandler): 

    @webapp2.cached_property 
    def jinja2(self): 
     # Returns a Jinja2 renderer cached in the app registry. 
     return jinja2.get_jinja2(factory=jinja2_factory) 

    def render_response(self, _template, **context): 
     # Renders a template and writes the result to the response. 
     rv = self.jinja2.render_template(_template, **context) 
     self.response.write(rv) 

Modifica: esempio modificato per utilizzare un RequestHandler

+1

Grazie mille! Mi piace davvero webapp2 ... E penso che ci stiamo avvicinando alla soluzione. – crushervx

+1

Aggiornato la mia domanda ... – crushervx

+1

La fabbrica può essere una funzione autonoma ... non ha bisogno di appartenere al gestore. – moraes

4

Qui è la soluzione più facile .. ;-) ho ... molte persone potrebbero già saperlo ma funziona alla grande.

env = jinja2.Environment(
    loader=jinja2.FileSystemLoader(root_path), 
    extensions=['jinja2.ext.autoescape', 
     'jinja2.ext.i18n', 
     CompilerExtension], 
    variable_start_string='[[', 
    variable_end_string=']]', 
    autoescape=True) 
env.globals = { 
    'uri_for': webapp2.uri_for 
} 

env.globals è la chiave :-)

Problemi correlati