Estoy creando un servidor que puede permitir a los clientes cargar y descargar datos de diferentes modelos. ¿Hay alguna forma elegante de manejar las solicitudes?

Más precisamente, no quiero hacer algo como esto,

app = webapp.WSGIApplication([
    ('/my_upload_and_download_url/ModelA/(.*)', MyRequestHandlerForA),
    ('/my_upload_and_download_url/ModelB/(.*)', MyRequestHandlerForB),
    ('/my_upload_and_download_url/ModelC/(.*)', MyRequestHandlerForC),
])
run_wsgi_app(app)

Ya que lo que hago dentro del controlador sería lo mismo. Por ejemplo,

class MyRequestHandlerForX(webapp.RequestHandler):
    def get(self, key=None):
        # return the instance with the designated key
    def post(self, key=None):
        # create/get the model instance
        # iterate through the property list of the instance and set the values

La única diferencia entre los controladores es crear instancias para modelos diferentes . Las URL son iguales y los controladores son casi iguales.

Revisé esta publicación sobre las solicitudes de redireccionamiento a otros controladores, y también he leído algunos métodos para crear una instancia con un nombre de clase; pero creo que ninguno de ellos es bueno.

¿Alguien tiene una buena solución?

PD. Esta es mi primera publicación acá. Si hay algo inapropiado por favor dígame, gracias.

2
Yi H. 29 ago. 2011 a las 20:21

3 respuestas

La mejor respuesta

Cómo hacerlo depende en gran medida de los detalles de su código en el controlador de solicitudes. Puedes hacer uno bastante genérico como este:

class ModelHandler(webapp.RequestHandler):
  def get(self, kind, key):
    model = db.class_for_kind(kind)
    instance = model.get(key)
    # Do something with the instance - eg, print it out

  def post(self, kind, key):
    model = db.class_for_kind(kind)
    instance = model.create_from_request(self.request)

application = webapp.WSGIApplication([
    ('/foo/([^/]+)/([^/]+)', ModelHandler),
])

def main():
  run_wsgi_app(application)

if __name__ == '__main__':
  main()

Esto supone que define un método de clase 'create_from_request' en cada clase de modelo; probablemente no desee hacerlo exactamente de esta manera, ya que combina estrechamente las definiciones de modelos con los formularios utilizados para ingresarlas; en su lugar, es probable que desee almacenar una asignación de nombre amable o clase a la función de controlador, o hacer sus formularios y creación de forma completamente automática al reflexionar sobre las propiedades de la clase. Como no ha especificado de qué se trata esto, no está seguro, es difícil ser más específico.

También tenga en cuenta la inclusión de una main() y otra plantilla anterior; Si bien funcionará de la manera en que lo ha pegado, agregar un main es sustancialmente más eficiente, ya que permite que el motor de ejecución de App Engine evite tener que evaluar su módulo en cada solicitud.

5
Nick Johnson 30 ago. 2011 a las 05:47

Podrías analizar la ruta de la URL y mirar hacia arriba, así:

import urlparse

model_lookup = {'ModelA':ModelA,'ModelB':ModelB, 'ModelC':ModelC}

class MyRequestHandler(webapp.RequestHandler):
    def get(self):
        url = urlparse.urlparse(self.request.uri)
        path_model = url.path.replace('/my_upload_and_download_url/','')
        model = model_lookup[path_model]
        ...

Lo que le permite usar la misma clase para cada ruta:

app = webapp.WSGIApplication([
    ('/my_upload_and_download_url/ModelA/(.*)', MyRequestHandler),
    ('/my_upload_and_download_url/ModelB/(.*)', MyRequestHandler),
    ('/my_upload_and_download_url/ModelC/(.*)', MyRequestHandler),
])
run_wsgi_app(app)
0
Kevin P 29 ago. 2011 a las 18:01

En su caso, probablemente simplemente haga que todo llegue a la misma ruta de URL y ponga los detalles en los parámetros GET, como /my_upload_and_download_url?model=modelA.

También puede usar webapp2 (http://webapp-improved.appspot.com/guide/app .html) que tiene un montón de soporte de enrutamiento de URL.

0
Steven Kampen 29 ago. 2011 a las 16:30