Reputation: 146
I want to get all of objects that are related to an instance of models.
Because my code is kinda generic, I pass the related table as an string and use eval()
function to convert it to the related table class. But I got an error.
Suppose that we have an instance of a table like self.casefile
; this is a part of my code:
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()
and I got this error:
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'
How can I pass the class name?
Upvotes: 2
Views: 1336
Reputation: 477685
You can not use eval(..)
for that. What you probably want to use here is 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 = getattr(self.casefile, table_name).all()
I am not sure you should use table_name += …
here however, since it will each time add more content to the table_name
. You likely want to use something like table_name = 'Files{}'.format(name.capitalize())
.
Note: normally related fields are not capitalized. One writes
users
oruser_set
, not.Users
Upvotes: 2
Reputation: 8222
Django provides a way to do this, although you do need to specify the name of the app in which the moodel is defined (because it's possible to have two models with the same name in different apps).
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.
Upvotes: 1