在调用filter()之前将字符串转换为Django模型名(不重复)


model_name = "MyModel" #This is coming from a different input, it can be any different string name not necessarily "MyModel"
model_name.objects.filter()
AttributeError: 'str' object has no attribute 'objects'

我已经试过了。

exec(model_name)
input(model_name)
[model_name]

我知道有一种可能的方法,您可以使用apps.get_model(model_name="string")导入模型,但我不想使用这种方法,因为模型已经预先导入。是否有其他方法可以将model_name(字符串类型)转换为可以插入INSERTHERE.objects.filter()的类型

更新:我知道一个更简单的实现是使用if + elif语句来查询正确的模型。我试图找到一种方法来避免使用if + 100 elif语句..

正如您所提到的,如果您想使用。objects,则需要首先获得Model对象。

from myapp.models import MyModel
MyModel.objects.all() # This works !

或者从字符串

开始
from django.apps import apps
MyModel = apps.get_model(app_label='myapp', model_name='MyModel')
MyModel.objects.all() # This works !

预先导入的模型没有问题,它实际上是一件好事,它允许您使用我写的第一个代码片段。

当您使用点符号时,例如foo.bar,您尝试从foo对象访问bar属性。

在django中,Model类(来自django.db.models)有一个名为objects的属性,它有filter(),all()等方法(=函数)。

您想要获得一个Model对象并访问它的objects属性以与您的数据库通信(例如,使用filter())

当您执行"MyModel".objects.all()时,您试图访问string对象的objects属性,而不是从Model对象,这就是为什么它不能以这种方式工作。

字符串不能直接成为类。在您的情况下,您可以使用字符串来Model类映射来直接查询信息,如下所示:

s2m_map = {'modelA': ModelA, 'modelB': ModelB, ...}
# OR
from django.apps import apps
s2m_map = {
model.__name__: model for model in apps.get_models()
}
# based on the comment in your question
objects = CODComputer.objects.filter(name='User Input')
for obj in objects:
model_name = object.saved_name
s2m_map[model_name].objects.all()

(但是)如果model_name不是字符串,而是ForeignKey关系,那么您可以使用以下代码:

model_name = object.saved_name.__class__
model_name.objects.all()

或者,您可以查看Generic ForeignKey,以支持直接使用不同类的模型(而不是字符串)。

最新更新