2012-01-12 14 views

Odpowiedz

13

Aby uniknąć tworzenia zduplikowanych URL: s do tej samej strony, należy użyć RedirectRoute z strict_slash ustawiony na true, aby automatycznie przekierować/feed/do/feed coś takiego:

from webapp2_extras.routes import RedirectRoute 

route = RedirectRoute('/feed', handler=feed, strict_slash=True) 

Czytaj więcej na http://webapp2.readthedocs.io/en/latest/api/webapp2_extras/routes.html

+1

Dzięki. Czy chcesz powiedzieć, że jeśli mam sto tras, potrzebuję również setek redirectroutów? Wygląda na strasznie niechlujne rozwiązanie. –

+1

Hi. Nie, zamieniasz trasy na RedirectRoutes, więc nie potrzebujesz obu. RedirectRoute wykonuje całą trasę, ale dodaje także opcję "strict_slash", a także inne funkcje przekierowania. Sprawdź link zamieszczony powyżej, aby uzyskać szczegółowe informacje. – Aneon

+0

To nie zawsze jest dobry pomysł. Jeśli Twój klient nie jest przeglądarką internetową (np. Jeśli piszesz api dostępne dla http na swojej stronie internetowej), może nie stosować się do przekierowania. – Ponkadoodle

-4

nie jestem zaznajomiony z webapp2, ale jeśli pierwszy parametr jest wyrażeniem regularnym, spróbuj:

/feed(/)? 
2

webapp2.Route szablon nie jest to wyrażenia regularne i twoja wartość jest uciekł z re.escape. Można użyć zasady stare stylu, który zapewnia regularne szablony wyrażenie:

webapp2.SimpleRoute('^/feed/?$', handler = feed) 
+0

Chcę kontynuować stosując własną składnię webapps' bez schodząc do regularnych wyrażeń regularnych. .. w tym sensie 'strict_slash' daje mi dokładnie to, co chcę, z najmniejszym kodem zmienionym. –

7

nie lubię klasę RedirectRoute ponieważ powoduje to niepotrzebne przekierowania HTTP.
Na podstawie dokumentacji dla webapp2 Route class, tutaj jest bardziej szczegółowa odpowiedź w tym wątku webapp2.Route with optional leading part.

Krótkie odpowiedzi

Moje wzory trasy działa dla następujących adresów URL.

  1. /
  2. /paszy
  3. /paszy/
  4. /paszy/tworzyć
  5. /paszy/tworzenia/
  6. /paszy/Edycja/{ENTITY_ID}
SITE_URLS = [ 
    webapp2.Route(r'/', handler=HomePageHandler, name='route-home'), 

    webapp2.Route(r'/feed/<:(create/?)|edit/><entity_id:(\d*)>', 
     handler=MyFeedHandler, 
     name='route-entity-create-or-edit'), 

    webapp2.SimpleRoute(r'/feed/?', 
     handler=MyFeedListHandler, 
     name='route-entity-list'), 
] 

Mam nadzieję, że pomoże :-)

4

Oto jak radzę sobie z tymi trasami.

from webapp2 import Route 
from webapp2_extras.routes import PathPrefixRoute 
import handlers 

urls = [ 
    Route('/foo<:/?>', handlers.Foo), 
    Route('/bars', handlers.BarList), 
    PathPrefixRoute('/bar', [ 
    Route('/', handlers.BarList), 
    Route('/<bar_id:\w+><:/?>', handlers.Bar), 
    ]), 
] 
... 

Ważne jest, aby pamiętać, że koparki będą musiały określić *args i **kwargs do czynienia z potencjalnym ukośnika, który zostanie wysłany do nich jako argument przy użyciu tej metody.

class Bar(webapp2.RequestHandler): 

    def get(bar_id, *args, **kwargs): 
    # Lookup and render this Bar using bar_id. 
    ... 
1

Szukałem sposobu, aby uczynić cięcie kursowe w katalogu głównym bloku PathPrefixRoute opcjonalnie.

Jeśli masz, powiedzmy:

from webapp2_extras.routes import RedirectRoute, PathPrefixRoute 

from webapp2 import Route 

app = webapp2.WSGIApplication([ 
    PathPrefixRoute('admin', [ 
     RedirectRoute('/', handler='DashboardHandler', name='admin-dashboard', strict_slash=True), 
     RedirectRoute('/sample-page/', handler='SamplePageHandler', name='sample-page', strict_slash=True), 
    ]), 
]) 

Będziesz mieć dostęp do /admin/, ale nie /admin.

Ponieważ nie mogłem znaleźć żadnego lepszego rozwiązania, Dodałem redirect_to_name do dodatkowego szlaku, jak:

from webapp2_extras.routes import RedirectRoute, PathPrefixRoute 

from webapp2 import Route 

app = webapp2.WSGIApplication([ 
    Route('admin', handler='DashboardHandler', name='admin-dashboard'), 
    PathPrefixRoute('admin', [ 
     RedirectRoute('/', redirect_to_name='admin-dashboard'), 
     RedirectRoute('/sample-page/', handler='SamplePageHandler', name='sample-page', strict_slash=True), 
    ]), 
]) 

Jestem zainteresowany lepszych rozwiązań tego problemu.

Czy powinienem wybrać rozwiązanie Stun i po prostu nie używać RedirectRoute?

+0

Możesz wypróbować moje rozwiązanie: http://stackoverflow.com/a/22223617/1175629 –

1

To działa dla mnie i jest bardzo proste. Wykorzystuje format szablonu do routingu URI w webapp2 Route class. Końcowe ukośnik w tym przykładzie jest opcjonalna bez przekierowania:

webapp2.Route('/your_url<:/?>', PageHandler) 

Wszystko po dwukropek między logo marki jest uważany za regex: <:regex>

+0

Warto zauważyć, że Twoje metody wymagają dodatkowego argumentu, który jest do dupy. – alex

+0

W każdym razie przekazuję '* args, ** kwargs' do moich metod, więc' get' for 'PageHandler' będzie' def get (self, * args, ** kwargs) ' – HorseloverFat

0

wymyśliłem pewien rodzaj hacky sposób. I zdefiniować następujące klasy:

class UrlConf(object): 

    def __init__(self, *args, **kwargs): 
     self.confs = [] 
     for arg in args: 
      if isinstance(arg, webapp2.Route): 
       slash_route = webapp2.Route(arg.template + '/', arg.handler) 
       self.confs += [arg, slash_route] 

    def __iter__(self): 
     for route in self.confs: 
      yield route 

Potem skonfigurować trasy tak:

MIRROR_URLS = list(UrlConf(
    Route('/path/to/stuff', handler=StuffHandler, name='stuff.page'), 
    Route('/path/to/more/stuff', handler= MoreStuffHandler, name='more.stuff.page') 
)) 

Jeśli zdecydujesz się pójść tą drogą, można oczywiście poprawić po to, aby być bardziej elastyczni inne typy obiektów BaseRoute.

1

Jeśli nie chcesz używać przekierowań (i pewnie nie), można zastąpić Route.match():

from webapp2 import Route, _get_route_variables 
import urllib 
from webob import exc 


class SloppyRoute(Route): 
    """ 
    A route with optional trailing slash. 
    """ 
    def __init__(self, *args, **kwargs): 
     super(SloppyRoute, self).__init__(*args, **kwargs) 

    def match(self, request): 
     path = urllib.unquote(request.path) 
     match = self.regex.match(path) 
     try: 
      if not match and not path.endswith('/'): 
       match = self.regex.match(path + '/') 
     except: 
      pass 
     if not match or self.schemes and request.scheme not in self.schemes: 
      return None 

     if self.methods and request.method not in self.methods: 
      # This will be caught by the router, so routes with different 
      # methods can be tried. 
      raise exc.HTTPMethodNotAllowed() 

     args, kwargs = _get_route_variables(match, self.defaults.copy()) 
     return self, args, kwargs 
Powiązane problemy