Python,如何从存储在数据库中的类实例化类?

Python,如何从存储在数据库中的类实例化类?,python,database,django,class,Python,Database,Django,Class,我正在使用Django,希望能够在数据库中存储表单和模型之类的类,这样我就可以通过用户界面轻松地创建它们,因为它们只存储在数据库中,而不是常规文件中。关于这一点我真的不太了解,也不确定这是否是一种需要在python中使用exec的情况,或者是否有其他方法。我在这上面的搜索没有发现什么 基本上,我只是在这里进行数据库调用并获取类的内容,然后我想实例化它。任何关于如何最好地完成这类事情的建议都将不胜感激 编辑:为了回应类中恶意的\uuuuuuu init\uuuuuu的想法,这些只适用于表单或模型之

我正在使用Django,希望能够在数据库中存储表单和模型之类的类,这样我就可以通过用户界面轻松地创建它们,因为它们只存储在数据库中,而不是常规文件中。关于这一点我真的不太了解,也不确定这是否是一种需要在python中使用exec的情况,或者是否有其他方法。我在这上面的搜索没有发现什么

基本上,我只是在这里进行数据库调用并获取类的内容,然后我想实例化它。任何关于如何最好地完成这类事情的建议都将不胜感激


编辑:为了回应类中恶意的
\uuuuuuu init\uuuuuu
的想法,这些只适用于表单或模型之类的东西,它们通过验证严格控制类中的内容,类中永远不会有
\uuuuuuu init\uuuuu
,这基本上是不可能的,因为我会在服务器端验证所有内容,将任何恶意代码放入类中。

不要在数据库中存储代码


假设一个类有一个恶意的
\uuuuu init\uuuu
方法,它在数据库中的“类存储库”中找到了自己的路径。这意味着任何对这些数据库表具有写访问权限的人都可以从web服务器读取任何文件,甚至可以对其文件系统进行核攻击,因为他们可以在其上执行任何python代码。

不要存储类本身,将导入路径作为字符串存储在数据库中(例如“django.forms.CharField”)

我开始为另一个项目做同样的事情,并将代码保存在本地存储库中。为了解决安全问题,我将向允许的基类的字段构造函数添加一个参数。如果你真的实施了这个,让我知道,我很想拥有它


好吧,我明白你的意思。。那么,建议采用什么方法?我想创建类似cms的功能,用户可以在其中创建表单(django中的类)和类似的东西。。我想我应该让它直接写文件,然后在数据库中跟踪它们?哦,而且这些没有init,因为它们只是表单类,通过大量的验证,它已经可以控制它们中的内容了,他们不可能创造一个定制的init@rick允许在数据库中找到的任意python代码按需执行是不安全的,无论您在那里进行了什么验证,您都会错过一些东西。您可以创建一个类似表单模型的东西,它将有一个字段模型,该字段模型将有一个名称/标签/类型等,从这些模型中您可以动态创建表单类,这需要一些表单如何在内部工作的知识,但是可行的。我建议你再问一个问题。好的,是的,我只是想找到正确的思路来解决这个问题,你说的从外键创建它,等等,听起来是个不错的方法,如果我找不到足够的信息,我会更深入地研究它,并围绕它创建一个新的问题,谢谢你的邀请help@Rick我想如果你用不同的措辞回答这个问题,你可能会得到更有用的答案。类似于“如何让用户使用Django创建表单”之类的东西,因为这似乎是您想要做的事情。您放入数据库中的类是否具有
\uuu init\uuu
并不重要。关键是攻击者可以在数据库中放入其他类,这些类具有
\uuuu init\uuuu
。另外,
\uuuuuu init\uuuuu
也是一个骗局。它也可以覆盖models
save
clean
方法。我知道,在实例化之前可以验证从数据库中获取的任何类,但这可能不值得费事,您可以解析文件并确保它满足某些标准,等等,但我认为瓦西里提到的另一种方法会更好谢谢你发表这篇文章,我一定会看一看。。我确实认为Vasil提出了一个很好的观点,所以我不知道我是否真的会在制作网站上使用这种方法,因为我正在考虑替代方法
def get_class_from_concrete_classpath(class_path):
    # Unicode will throw errors in the __import__ (at least in 2.6)
    class_path = str(class_path)

    mod_list = class_path.split('.')
    module_path = '.'.join(mod_list[:-1])
    class_name = mod_list[-1]

    base_mod = __import__(module_path, fromlist=[class_name,])
    return getattr(base_mod, class_name)


def get_concrete_name_of_class(klass):
    """Given a class return the concrete name of the class.

    klass - The reference to the class we're interested in.

    Raises a `TypeError` if klass is not a class.
    """

    if not isinstance(klass, (type, ClassType)):
        raise TypeError('The klass argument must be a class. Got type %s; %s' %
                        (type(klass), klass))

    return '%s.%s' % (klass.__module__, klass.__name__)
class ClassFormField(forms.Field):
    def to_python(self, value):
        return get_concrete_name_of_class(value)

class ClassField(models.CharField):
    __metaclass__ = models.SubfieldBase

    """Field used for storing a class as a string for later retrieval"""

    MAX_LENGTH = 255
    default_error_messages = {
        'invalid': _(u'Enter a valid class variable.'),
    }

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = kwargs.get('max_length', ClassField.MAX_LENGTH)
        super(ClassField, self).__init__(*args, **kwargs)

    def get_prep_value(self, value):
        if isinstance(value, (basestring, NoneType)):
            return value

        return get_concrete_name_of_class(value)


    def to_python(self, value):
        if isinstance(value, basestring):
            return get_class_from_concrete_classpath(value)

        return value

    def formfield(self, **kwargs):    
        defaults = {'form_class' : ClassFormField}
        defaults.update(kwargs)
    return super(ClassField, self).formfield(**defaults)