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

时间:2022-05-15 06:38:54

I have a URL route that captures the name of the model for which the entity will be created.(e.g. '/New<model>/') Now, I have the model name as a string. How can I take that string and use it to create a new entity of this model to put in the datastore?

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

I'm building a custom admin interface for GAE with the ability to register new models and have forms built dynamically based on registered models. I need a way to then be able to take the posted data submitted by the admin user and put it into the datastore using the correct model which will be in the URL the form is posted to. I'm currently building a handler to process requests coming into that URL scheme but have hit this roadblock. Any help is greatly appreciated.

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

2 个解决方案

#1


0  

Although you could access the model class with

虽然您可以使用访问模型类

globals()[modelname]

if the model class is defined at the module level, as @TimHoffman points out in the comments, it is generally not a good idea to allow (potentially malicious) users arbitrary access to your globals.

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

Since you are generating model classes dynamically, a safer way would be to save those model classes in a dict:

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

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

and then given the string name modelname, you could access the class with

然后给出字符串名称modelname,您可以访问该类

model[modelname]

#2


0  

I didn't use globals to get at my class constructor. Instead, I made a variable that points to the current module and used getattr to capture my class constructor. Here's my handler in case anyone else wants to see what I did.

我没有使用全局变量来获取我的类构造函数。相反,我创建了一个指向当前模块的变量,并使用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 is captured from the URL.

从URL捕获的东西。

#1


0  

Although you could access the model class with

虽然您可以使用访问模型类

globals()[modelname]

if the model class is defined at the module level, as @TimHoffman points out in the comments, it is generally not a good idea to allow (potentially malicious) users arbitrary access to your globals.

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

Since you are generating model classes dynamically, a safer way would be to save those model classes in a dict:

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

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

and then given the string name modelname, you could access the class with

然后给出字符串名称modelname,您可以访问该类

model[modelname]

#2


0  

I didn't use globals to get at my class constructor. Instead, I made a variable that points to the current module and used getattr to capture my class constructor. Here's my handler in case anyone else wants to see what I did.

我没有使用全局变量来获取我的类构造函数。相反,我创建了一个指向当前模块的变量,并使用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 is captured from the URL.

从URL捕获的东西。