GAE / Python - 将请求从控制器传递给模型的最佳方法是什么?

时间:2012-05-12 18:34:23

标签: python google-app-engine request

在下面的示例代码中,我将说明如何解决将请求从控制器传递到模型的问题。有更好的方法吗?

模型/ MyModel.py

from google.appengine.ext import db

class MyModel(db.model):
    a = db.StringProperty(required=True)
    b = db.StringProperty(required=True)
    c = db.StringProperty(required=True)

class Update:
    def __init__(self, x)
        self.x = x

    def do_something(self)
        myquery = db.GqlQuery('SELECT * FROM MyModel WHERE a = :1' self.x)
        v = myquery.get()

        if not v:
            somevalue = MyModel(a = self.request.get('a'), # Doesn't work unless
                                b = self.request.get('b'), # the request has been
                                c = self.request.get('c')) # passed
            somevalue.put()

控制器/ MyController.py

import webapp2
from models.MyModel import Update

class WebHandler(webapp2.RequestHandler):
    def get(self):
        var_x = "string"
        var_y = "string"
        z = Update(var_x)
        z.request = self.request  # <--- Is there a better way?
        z.do_something()

编辑:(5/30/2012) 我最终创建了一个函数来将请求变量作为参数传递给Model。我希望有一些蟒蛇魔法可以避免所有重复,但我找不到。

3 个答案:

答案 0 :(得分:4)

将请求移交给模型意味着您正在混合模型和控制器。

通常,模型甚至不应该意识到甚至是一个请求。从请求中获取参数是控制器的工作,而不是模型。如果你的do_something方法必须使用参数,那么它应该将它们作为参数并返回结果(通常是实体)。

答案 1 :(得分:2)

你需要更多的封装。另一个抽象层次很有用。

使用MyModelab属性或属性创建一个表示您正在使用c来保存的实际内容的类:

class Thing(object):

   def __init__(a, b, c):
      self.a = a
      self.b = b
      self.c = c 

此类对请求,数据存储区或持久性一无所知。这就是围绕事物本身的所有实际业务逻辑所在的地方。

您可以在不需要请求或数据库的情况下实例化此类,并且您可以对所有业务逻辑进行单元测试,而无需模拟任何GAE的管道。

然后,您可以在请求处理程序中编写实例化此内容的代码,例如:

def get(request):
  thing = Thing(a=request.get('a'), b=request.get('b'), c=request.get('c'))
  u = Update(some_params)
  u.do_something(thing)

您可以向MyModel添加一个类方法,例如:

@classmethod
def put_thing(thing):
  model = MyModel(a=thing.a, b=thing.b, c=thing.c)
  model.put()

然后,如果需要将do_something逻辑添加到数据库,则MyModel.put_thing(thing)逻辑可以调用{{1}}。

答案 2 :(得分:1)

您可以使用@classmethod装饰器将更新作为类方法添加到MyModel类,并调用MyModel.update(a = x)