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

qlzsbp2j  于 2023-04-07  发布在  Go
关注(0)|答案(2)|浏览(85)
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语句。

afdcj2ne

afdcj2ne1#

正如你提到的,如果你想使用.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对象,这就是为什么它不能以这种方式工作。

guz6ccqo

guz6ccqo2#

字符串不能直接是一个类。在你的例子中,你可以使用字符串到Model类Map来直接查询信息,像这样:

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()

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

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

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

相关问题