You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将字符串转为Django模型类以调用filter()方法(非重复问题)

解决字符串模型名转模型类的问题

场景还原

你现在的问题是手里拿着字符串形式的模型名(比如model_name = "MyModel"),直接调用model_name.objects.filter()会报AttributeError: 'str' object has no attribute 'objects',因为字符串不是模型类对象。之前试的exec(model_name)、input(model_name)、[model_name]都没效果,而且不想用apps.get_model(),也不想写一堆if-elif匹配。

可行方案

方案1:利用全局变量字典 globals()

如果你的模型已经提前导入到当前全局作用域里,直接从globals()字典里取就行:

model_name = "MyModel"
# 从全局命名空间中获取对应的模型类
model_class = globals().get(model_name)

if model_class:
    # 现在可以正常调用objects方法了
    queryset = model_class.objects.filter(...)
else:
    # 处理模型名不存在的情况,比如抛个提示
    print(f"模型 {model_name} 未找到")

注意:如果当前全局作用域里有和模型名同名的其他变量,可能会取错,所以这个方法适合模型名唯一且确定在全局的场景。

方案2:结合模块和getattr()(更推荐)

如果你的模型都集中在某个模块里(比如myapp.models),先导入模块,再用getattr()拿对应的类:

from myapp import models  # 替换成你的模型所在模块

model_name = "MyModel"
# 从指定模块中获取模型类,第三个参数是找不到时的默认值
model_class = getattr(models, model_name, None)

if model_class:
    queryset = model_class.objects.filter(...)
else:
    print(f"模型 {model_name} 在模块中不存在")

这个方法更安全,因为限定了模块范围,不会误拿到其他同名变量,也符合Django模型的常规组织方式。

为什么之前的方法无效?

  • exec(model_name):只是执行字符串代码,比如exec("MyModel")并不会返回模型类,就算改成exec(f"model_class = {model_name}")也有安全风险,不建议用。
  • input(model_name):这是用来接收用户输入的函数,和转换模型类完全无关。
  • [model_name]:只是把字符串放进列表,本质还是字符串,不是模型类对象。

内容的提问来源于stack exchange,提问作者CODComputerAtWar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:37:10