Let's simplify your question a little bit, and let's remove the django part first. Let's say you have a class with name A
, then you can set an attribute on A
with
class A: pass
A.foo = 'bar'
Alternatively, you can also do
setattr(A,'bar','baz')
You can verify that those are indeed equivalent by checking
print(A.foo) # bar
print(A.bar) # baz
So if you are defining a normal class, you can pretty much just loop through your dict
and set things with setattr
calls, in which case you have the control of the variable name.
And when we bring Django into the question, things are a bit more complicated...There are some very strange and magical things happening when you initialize a Model
class. Basically it does a lookup on things already defined, and transforms all the defined fields through the pretty much public private _meta
API. This means that adding class attributes outside of definition time won't work, and you might have to use a bit of a hack to construct a class directly through its metaclass (in case you are not familiar with Python's metaclasses, a class is basically an instance of its metaclass).
The basic syntax for dynamically constructing a class is through the type
call with 3 arguments: type(name, bases, dict)
. In your example,
class Host_main(models.Model):
host_name = models.CharField(max_length=20, unique=True, help_text=test_dict['host_name'])
def __str__(self):
return self.host_name
is the equivalent of
def Host_main_str(self): # the name here doesn't really matter unless you care about the __name__ attribute of the function, which you can overwrite.
return self.host_name
Host_main = type('Host_main', (models.Model,), {
'__str__': Host_main_str,
'host_name': models.CharField(max_length=20, unique=True, help_text=test_dict['host_name'])
})
It's actually how django constructs all their QuerySet classes (there were some more crazy things django did with dynamic class constructions if I remember correctly but I couldn't find a good example)
So, you can do things like
attr_dict = {'__str__':'Host_main_str'}
for name, help_text in test_dict.values():
attr_dict[name] = models.CharField(max_length=20, unique=True, help_text=help_text)
Host_main = type('Host_main', (models.Model,), attr_dict)
if you really insist on loop through a dictionary.