Первое добавление новых атрибутов в класс:
>>> class_changer("models.Staff", "gender", BooleanField()) # Add new field to Staff
>>> class_changer("models.Staff", "country", ForeignKey("Country")) # Add new field to Staff
Для этих двух, просто продолжайте и установите Staff
напрямую:
models.Staff.gender = BooleanField()
models.Staff.country = ForeignKey("Country")
Или сделать его общим:
def add_to_class(cls, name, attr):
setattr(cls, name, attr)
add_to_class(models.Staff, "gender", BooleanField())
add_to_class(models.Staff, "country", ForeignKey("Country"))
Во-вторых, создание нового класса:
>>> class_changer("models.Country", "name", StringField()) # Add new class with name field
Вы можете создать класс в функции и затем назначить его модулю:
def new_class(mod, name):
class New(object): pass
setattr(mod, name, New)
new_class(test, "Country")
add_to_class(test, "Country", StringField())
Я не уверен, что вы захотите объединить new_class
и add_to_class
, но я полагаю, вы могли бы сделать:
def create_if_needed_and_add_to_class(mod, clsname, attrname, value):
if clsname not in dir(mod):
new_class(mod, clsname)
add_to_class(mod, attrname, value)
и, наконец, для вашего class_changer
:
def class_changer(mod_clsname_string, attrname, value):
modname, clsname = '.'.split(mod_clsname_string)
create_if_needed_and_add_to_class(globals()[modname], clsname, attrname, value)
Редактировать: исправлено class_changer
для использования locals()
для поиска имени модуля, поскольку это строка, а не модуль.
Редактировать: упс, должно быть globals()
.