clifgray
clifgray

Reputation: 4419

use url parameter to specify how python handles the request

okay so this seemed like it should be pretty basic but I just can't get it to work. I am getting a 404 error saying that the resource cannot be located, though I am being directed to the correct address, www.url.com/sea?s='1' for sailing for example. I have a list of links with different query parameters and I want them to be handled differently by my python code. I am using google app engine with python and a jinja2 template system.

Here is my HTML:

  <h3><a href="/" class="center-it">Quick Navigation</a></h3>
    <div class="span1">
    <div class="span1">
      <h4><a href="/sea">Sea</a></h4>
        <ul>
            <li><a href="/sea?s='1'">Sailing</a></li>
            <li><a href="/sea?s='2'">Diving</a></li>
            <li><a href="/sea?s='3'">Surfing</a></li>
            <li><a href="/sea?s='4'">Kite Boarding</a></li>
            <li><a href="/sea?s='5'">Kayaking</a></li>
        </ul>
   </div>

and here is the python:

class Sea(BlogHandler):
    def get(self, s):
        s = self.request.get('s')
        if s == '1':
            posts = posts = db.GqlQuery("select * from Post where sport=:1 order by created desc limit 30", "sailing")
        elif s == '2':
            posts = posts = db.GqlQuery("select * from Post where sport=:1 order by created desc limit 30", "diving")
        elif s == '3':
            posts = posts = db.GqlQuery("select * from Post where sport=:1 order by created desc limit 30", "surfing")
        elif s == '4':
            posts = posts = db.GqlQuery("select * from Post where sport=:1 order by created desc limit 30", "kiteboarding")
        elif s == '5':
            posts = posts = db.GqlQuery("select * from Post where sport=:1 order by created desc limit 30", "kayaking")
        else:
            posts = posts = db.GqlQuery("select * from Post where element=:1 order by created desc limit 30", "sea")

        global visits
        user = users.get_current_user()
        logout = users.create_logout_url(self.request.uri)        
        self.render('sport.html', user = user, posts=posts, visits = visits, logout=logout)

UPDATE: The problem wasn't actually with the code it was with my URL handling. This is correct:

app = webapp2.WSGIApplication([('/', MainPage),
                               (r'/sea', Sea)]

Upvotes: 0

Views: 416

Answers (1)

Jeff Tratner
Jeff Tratner

Reputation: 17126

The 404 error is coming on not because of anything wrong in your page, but rather because something is wrong with your routes or your app.yaml file. If you are using webapp2, you just need to define a route that has the url r'/air' and it should work. (e.g. webapp2.Route(r'/sea/', handler=Sea)

By the way, instead of using query strings in your get request, you could put those in as route kwargs and do nicer things, e.g. (the syntax is <KEYWORDNAME:REGULAREXPRESSION> when no keyword name is given (like in <:/?>) it just matches the regex and doesn't pass anything through to you)

webapp2.Route(r'/sea<:/?><activity:[a-zA-Z]*?>', defaults={"activity":""}, handler=Sea, name="sea")

And then you could change your urls to, for example:

<a href="/sea/sailing">Sailing</a>

The only other change you need to make is in your Handler function. It needs to accept kwargs. (so you can literally just change your get request slightly):

get(self, *args, **kwargs):
    activity = kwargs.get("activity")
    if activity in ("sailing", "kayaking", "hiking", "kiteboarding", "surfing", "diving")
       posts = db.GqlQuery("select * from Post where sport=:1 order by created desc limit 30", activity)
    elif activity:
       self.error(404)
    else:
       posts = db.GqlQuery ... etc

Which would simplify your code quite a bit and let you make it more flexible. Further, if your site doesn't update very often, you could do a bit of caching to make the queries snappier, etc.

Upvotes: 1

Related Questions