如何在 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.
我想获取与模型实例相关的所有对象。
因为我的代码有点通用,所以我将相关的 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
oruser_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.