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

如何在Django中获取参与者最新的CheckIn记录并传递至模板

解决Django中获取每个参与者最新签到记录的问题

方法一:使用Prefetch预取最新签到记录

这种方法直观高效,通过自定义Prefetch对象,为每个参与者预取其最新的一条签到记录,直接传递到模板使用。

修改View代码

from django.db.models import Prefetch

def your_view(request):
    # 定义Prefetch对象,筛选每个参与者的最新签到记录(按签到时间倒序取第一条)
    latest_checkin_prefetch = Prefetch(
        'adult_checkin',  # 对应CheckIn模型中related_name的取值
        queryset=CheckIn.objects.order_by('-checkin').filter(checkin__isnull=False)[:1],  # 排除无签到时间的无效记录
        to_attr='latest_checkin'  # 自定义属性名,用于模板中访问
    )

    # 获取所有参与者并预取最新签到记录,如需排序请确保对应字段存在(如原代码的created需在Participant模型中定义)
    p_checkins = Participant.objects.all().prefetch_related(latest_checkin_prefetch)
    # 若需按创建时间排序:p_checkins = Participant.objects.all().order_by('-created').prefetch_related(latest_checkin_prefetch)

    context = {
        "the_list": p_checkins
    }
    return render(request, 'list_of_checkins.html', context)

模板中调用

在list_of_checkins.html中,通过自定义属性访问最新记录(注意它是单元素列表,取第一个元素即可):

{% for participant in the_list %}
    <div class="participant-card">
        <h3>{{ participant.first_name }} {% if participant.middle_initial %}{{ participant.middle_initial }}.{% endif %}</h3>
        {% if participant.latest_checkin %}
            {% with latest_record=participant.latest_checkin.0 %}
                <p>最新签到:{{ latest_record.checkin|date:"Y-m-d H:i:s" }}</p>
                {% if latest_record.checkout %}
                    <p>最新签出:{{ latest_record.checkout|date:"Y-m-d H:i:s" }}</p>
                {% else %}
                    <p style="color: #ff7f0e;">当前未签出</p>
                {% endif %}
            {% endwith %}
        {% else %}
            <p>暂无签到记录</p>
        {% endif %}
    </div>
{% endfor %}

方法二:使用子查询标注最新签到记录

通过Subquery和OuterRef为每个参与者标注最新签到时间,再关联对应的签到记录对象。

View代码示例

from django.db.models import Subquery, OuterRef

def your_view(request):
    # 子查询:获取每个参与者的最新签到时间
    latest_checkin_time = CheckIn.objects.filter(
        adult=OuterRef('pk'),
        checkin__isnull=False
    ).order_by('-checkin').values('checkin')[:1]

    # 为参与者标注最新签到时间
    participants = Participant.objects.annotate(
        latest_checkin_time=Subquery(latest_checkin_time)
    )

    # 子查询:获取对应最新签到时间的完整记录
    latest_checkin_record = CheckIn.objects.filter(
        adult=OuterRef('pk'),
        checkin=OuterRef('latest_checkin_time')
    ).values('id', 'checkin', 'checkout')[:1]

    # 为参与者标注最新签到记录对象
    participants = participants.annotate(
        latest_checkin=Subquery(latest_checkin_record)
    )

    context = {
        "the_list": participants
    }
    return render(request, 'list_of_checkins.html', context)

模板中调用

{% for participant in the_list %}
    <div class="participant-card">
        <h3>{{ participant.first_name }} {% if participant.middle_initial %}{{ participant.middle_initial }}.{% endif %}</h3>
        {% if participant.latest_checkin %}
            <p>最新签到:{{ participant.latest_checkin.checkin|date:"Y-m-d H:i:s" }}</p>
            {% if participant.latest_checkin.checkout %}
                <p>最新签出:{{ participant.latest_checkin.checkout|date:"Y-m-d H:i:s" }}</p>
            {% else %}
                <p style="color: #ff7f0e;">当前未签出</p>
            {% endif %}
        {% else %}
            <p>暂无签到记录</p>
        {% endif %}
    </div>
{% endfor %}

注意事项

  • 原View中的order_by('created')会报错,需在Participant模型中添加created = models.DateTimeField(auto_now_add=True)字段,或更换为其他存在的字段(如first_name)排序。
  • 过滤checkin__isnull=False是为了排除无效记录,可根据业务需求调整。
  • 若需按签出时间判断“最新”,只需将order_by('-checkin')改为order_by('-checkout')。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:36:16