Django模板标签中调用ContentType.objects.get报DoesNotExist错误
Django模板标签ContentType查询不存在问题排查方案
核心故障点定位
视图层相同查询逻辑正常、模板标签触发DoesNotExist的核心差异在模板调用参数处理:你在模板中对传入的modelname加了|title过滤器,破坏了参数匹配规则。
Django框架django_content_type表中model字段存储的是全小写格式的模型名,和模型类Meta配置的model_name一致,默认是模型类名转全小写生成。而title过滤器会把传入字符串处理为首字母大写、其余字母小写的格式(例如传入srrpitem会输出Srrpitem),大小写不匹配自然无法命中查询。
视图层代码直接读取URL参数中的原始modelname值,没有做格式转换,和数据库存储值匹配,因此可以正常返回结果。
修复方案
直接移除模板调用时的|title过滤器,传入原始全小写格式的modelname即可:
{% get_object modelname primary %}
进阶排查&优化
如果移除过滤器后仍报错,按以下步骤处理:
- 在模板标签函数中加临时日志,打印实际接收到的参数值,和数据库
django_content_type表的存储值逐字对比,排查是否存在多余空格、特殊字符、传值错误问题:@register.simple_tag def get_object(modelname, id): # 临时调试用,确认参数值后可删除 print(f"接收参数modelname: {repr(modelname)}, id: {repr(id)}") ctype = ContentType.objects.get(model=modelname) model = ctype.model_class() return model.objects.get(pk=id) - 如果项目中存在多个app下同名模型的情况,查询ContentType时建议同时传入
app_label参数做过滤,避免命中错误记录 - 增加异常兜底逻辑,避免单条数据查询失败导致整个页面崩溃,同时对传入的modelname统一转小写做兼容:
from django import template from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist register = template.Library() @register.simple_tag def get_object(modelname, id): try: ctype = ContentType.objects.get(model=modelname.lower()) model = ctype.model_class() return model.objects.get(pk=id) except ObjectDoesNotExist: return None
内容的提问来源于stack exchange,提问作者Pandaeyes
相关产品推荐
相关产品推荐

