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

Django模板循环中自定义filter返回值不更新是什么原因

问题成因
  • Django原生QuerySet仅支持存放同一模型的实例,如果你是通过QuerySet.union()方法拼接多个不同模型的查询集来得到links,union返回的所有实例都会被强制转换为首个调用union的查询集所属的模型类型,调用_meta.verbose_name时自然全部返回第一个模型的别名。
  • 如果你是用通用外键关联不同模型,直接传通用外键的中间模型实例给过滤器,而没有取到实际关联的业务模型实例,也会出现返回值不符合预期的情况。
解决方案
  1. 调整视图层的links构造逻辑:不要使用union拼接不同模型的查询集,改为将查询集转为普通Python列表后再合并,保留每个实例的原始模型类型:
# 视图代码示例
from your_app.models import Unit, OtherModel

def your_view(request):
    # 分别查询不同模型的实例,转为列表后合并
    unit_list = list(Unit.objects.filter(your_condition=xxx))
    other_list = list(OtherModel.objects.filter(your_condition=xxx))
    links = unit_list + other_list
    return render(request, "your_template.html", {"links": links})
  1. 优化自定义过滤器的健壮性,兼容更多传参场景:
from django import template

register = template.Library()

@register.filter
def verbose_name(obj):
    # 优先取实例对应模型的verbose_name
    if hasattr(obj, "_meta"):
        return obj._meta.verbose_name
    # 兼容直接传入模型类的场景
    if hasattr(obj, "__class__") and hasattr(obj.__class__, "_meta"):
        return obj.__class__._meta.verbose_name
    return ""
  1. 如果使用了通用外键,模板调用过滤器时要传入实际的关联对象:
{% load to_and %}
{% for link in links %}
    <!-- content_object才是实际关联的不同模型的实例 -->
    {% if link.content_object|verbose_name == "Unit" %}
        {{ link.content_object|verbose_name }}
        {{ link.content_object.id }}
    {% endif %}
{% endfor %}

内容的提问来源于stack exchange,提问作者Habib Ur Rehman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:45:05