Python. Динамическая подстановка имени типа класса
Необходимо реализовать метод обращения к БД с целью извлечения определённого экземпляра - записи с конкретным номером, например средствами фреймворка Django. Для этой цели сейчас используется функция:
def get_instance(pk=None):
''' возвращает экземпляр модели из БД по ключю pk'''
instance = Entry.objects.filter(id=pk) // Entry - тип модели в БД, он же класс объектов
return instance[0] if instance.exists() else None
В приведенной функции используется конкретно заданное имя класса.
Как в этом случае можно обратиться к другой модели в БД, динамически подставив её тип в параметры данного метода? Например, с помощью параметра classType и какой синтаксис будет у classType?
def get_instance(classType, pk=None):
instance = classType.objects.filter(id=pk) // classType- тип модели в БД, он же класс объектов
return instance[0] if instance.exists() else None
Ответы (2 шт):
Автор решения: Константин Комиссаров
→ Ссылка
Можно использовать first. Он вернет None, если нужных объектов не окажется
def get_instance(classType, pk=None):
return classType.objects.filter(id=pk).first()
А взять класс по имени можно с помощью getattr
from myapp import models
class_name = 'MyModel'
model = getattr(models, class_name)
model.objects.filter(id=pk).first()
Автор решения: JBlack
→ Ссылка
Сработал тривиальный вариант подстановки типа класса:
def get_instance(classType, pk=None):
return type(classType()).objects.filter(id=pk).first()
Результат выполнения (Python 3.6):
>>> type(Entry)
<class 'django.db.models.base.ModelBase'> // тип, шаблон класса
>>> type(Entry())
<class 'app.models.Entry'> // тип экземпляра класса
>>> get_instance(Entry, 1)
<Entry: id:1 № НЗН-1 от 13.05.2020> // экземпляр из БД