如何在 Django 模型中使用字符串传递 class 名称

How to pass a class name with a string in Django models

我想获取与模型实例相关的所有对象。 因为我的代码有点通用,所以我将相关的 table 作为字符串传递,并使用 eval() 函数将其转换为相关的 table class。但是我得到了一个错误。 假设我们有一个 table 的实例,比如 self.casefile;这是我的代码的一部分:

 def related_models_migration(self):
        opts = self.casefile._meta
        table_name = 'Files'
        for f in opts.many_to_many:
            name = ''.join(f.name.split('_'))
            table_name += name.capitalize()
            objects = self.casefile.eval(table_name).all()

我得到了这个错误:

AttributeError                            Traceback (most recent call last)
<ipython-input-6-025484eeba97> in <module>
----> 1 obj.related_models_migration()

~/Documents/kangaroo/etl/data_migration.py in related_models_migration(self)
     28             name = ''.join(f.name.split('_'))
     29             table_name += name.capitalize()
---> 30             objects = self.casefile.eval(table_name).all()
     31 
     32             for d in dir(etl.models):

AttributeError: 'FilesCasefiles' object has no attribute 'eval'

如何传递 class 名称?

您不能为此使用 eval(..)。您可能想在这里使用的是 getattr(..):

def related_models_migration(self):
    opts = self.casefile._meta
    table_name = 'Files'
    for f in opts.many_to_many:
        name = ''.join(f.name.split('_'))
        table_name += name.capitalize()
        objects = <b>getattr(</b>self.casefile, table_name<b>)</b>.all()

我不确定您是否应该在这里使用 table_name += …,因为它每次都会向 table_name 添加 更多 内容。您可能想使用 table_name = 'Files{}'.format(name.capitalize()).

之类的东西

Note: normally related fields are not capitalized. One writes users or user_set, not Users.

Django 提供了 a way to do this, 尽管您确实需要指定定义 moodel 的应用程序的名称(因为在不同的应用程序中可能有两个具有相同名称的模型)。

apps.get_model(app_label, model_name, require_ready=True)¶

Returns the Model with the given app_label and model_name. As a shortcut, this method also accepts a single argument in the form app_label.model_name. model_name is case-insensitive.