如何在运行时确定的类型的GAE数据存储中创建实体?

时间:2013-03-08 14:02:53

标签: python google-app-engine google-cloud-datastore

我有一个URL路由,用于捕获将为其创建实体的模型的名称。(例如'/New<model>/')现在,我将模型名称作为字符串。如何获取该字符串并使用它来创建此模型的新实体以放入数据存储区?

我正在为GAE构建一个自定义管理界面,能够注册新模型并根据已注册的模型动态构建表单。我需要一种方法,然后能够获取管理员用户提交的已发布数据,并使用正确的模型将其放入数据存储区,该模型将在表单发布到的URL中。我目前正在构建一个处理程序来处理进入该URL方案的请求,但是遇到了这个障碍。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

虽然您可以使用

访问模型类
globals()[modelname]

如果在模块级别定义模型类,正如@TimHoffman在注释中指出的那样,允许(可能是恶意的)用户任意访问您的全局变量通常不是一个好主意。

由于您是动态生成模型类,因此更安全的方法是将这些模型类保存在dict中:

model = { 'MyModel': MyModelClass, ... }

然后给出字符串名称modelname,您可以使用

访问该类
model[modelname]

答案 1 :(得分:0)

我没有使用全局变量来获取我的类构造函数。相反,我创建了一个指向当前模块的变量,并使用getattr来捕获我的类构造函数。这是我的处理程序,以防其他人想看到我做了什么。

class NewThingHandler(BaseRequestHandler):
    def get(self, thing):
        self.redirect('/admin/')
    def post(self, thing):
        this_module = sys.modules[__name__]
        ThisModel = getattr(this_module, thing)
        arguments = {}
        for property in ThisModel.properties().keys():
            if type(ThisModel._properties[property]) is db.DateProperty:
                this_date = map(int, self.request.get(property).split('/'))
                this_date = datetime.date(this_date[2], this_date[0], this_date[1])
                arguments[property] = this_date
                continue
            arguments[property] = self.request.get(property)

        new_thing = ThisModel(**arguments)
        new_thing.put()
        self.redirect('/admin/')
从网址捕获

thing