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

Django ListView如何向模板传递User实例的动态条件属性today_note

实现方案

方案1:最小改动适配现有逻辑

你当前代码的问题是处理完添加了today_note属性的员工列表没有绑定到context上下文对象中,直接在循环处理完成后给context的employees键赋值即可,修改后的视图代码如下:

from django.db.models import Q
from datetime import date

class AllEmployeesList(ListView):
    template_name = "users/all_employees.html"
    model = User
    context_object_name = 'employees'

    def get_context_data(self, **kwargs):
        context = super(AllEmployeesList, self).get_context_data(**kwargs)
        all_employees = User.objects.order_by('first_name', 'last_name').all()
        today = date.today()

        for employee in all_employees:
            # 这里用.exists()替代len(xxx.all()),查询效率更高
            today_sick = Sickleave.objects.filter(
                Q(start_date__lte=today)
                & Q(end_date__gte= today)
                & Q(employee__id=employee.id)
            ).exists()
            employee.today_note = "C" if today_sick else "✓"
        
        # 把处理后的员工列表赋值给context,替换默认生成的员工列表
        context['employees'] = all_employees
        return context

模板调用方式和你之前的逻辑一致,直接遍历即可:

{% for employee in employees %}
{{ employee.today_note }}
{% endfor %}

方案2:性能优化版(解决N+1查询问题)

上述方案如果员工数量较多会产生N+1次数据库查询(1次查所有员工,每个员工单独查1次病假记录),可以用Django的annotate+Exists一次性完成状态标注,全程只需要2次数据库查询:

from django.db.models import Exists, OuterRef, Value, Case, When, CharField
from datetime import date

class AllEmployeesList(ListView):
    template_name = "users/all_employees.html"
    model = User
    context_object_name = 'employees'

    def get_queryset(self):
        today = date.today()
        # 子查询:判断当前员工是否在今日病假范围内
        sick_leave = Sickleave.objects.filter(
            employee=OuterRef('pk'),
            start_date__lte=today,
            end_date__gte=today
        )
        # 给查询集直接添加today_note注解
        return super().get_queryset().annotate(
            today_sick=Exists(sick_leave)
        ).annotate(
            today_note=Case(
                When(today_sick=True, then=Value("C")),
                default=Value("✓"),
                output_field=CharField()
            )
        ).order_by('first_name', 'last_name')

这个方案不需要额外修改get_context_data,注解生成的today_note可以直接在模板中调用,使用方式和方案1完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 18:24:02