1

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

模型/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)我最终创建了一个函数来将请求变量作为参数传递给模型。我希望有一些蟒蛇魔法可以避免所有重复,但我没有找到。

4

3 回答 3

4

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

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

于 2012-05-12T19:10:52.167 回答
2

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

创建一个表示您MyModel用于持久化的实际事物的类,使用abc属性或属性:

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)需要将其添加到数据库时调用。

于 2012-05-12T20:30:56.723 回答
1

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

于 2012-05-12T18:56:34.333 回答