在下面的示例代码中,我将说明如何解决将请求从控制器传递到模型的问题。有更好的方法吗?
模型/ 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。我希望有一些蟒蛇魔法可以避免所有重复,但我找不到。
答案 0 :(得分:4)
将请求移交给模型意味着您正在混合模型和控制器。
通常,模型甚至不应该意识到甚至是一个请求。从请求中获取参数是控制器的工作,而不是模型。如果你的do_something
方法必须使用参数,那么它应该将它们作为参数并返回结果(通常是实体)。
答案 1 :(得分:2)
你需要更多的封装。另一个抽象层次很有用。
使用MyModel
,a
和b
属性或属性创建一个表示您正在使用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)