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

Django多表关联展示问题:如何显示活动参与者的报名详情

解决Django模板无法显示Submission模型details字段的问题

问题描述

搭建活动报名页面,参与者报名需填写个人详情,在Django视图中尝试展示参与者姓名、头衔及对应报名详情,但模板无法正确获取并显示Submission模型的details字段。

相关代码

模型代码

# Event 模型
class Event(models.Model):
    Event_ID = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
    Event_Description = RichTextField(null=True, blank=True)
    Event_Category = models.ForeignKey(EventCategories, default=1, on_delete=models.CASCADE)
    Event_participants = models.ManyToManyField(User, blank=True, related_name='events')

    def __str__(self):
        return self.Event_Name  # 注意:模型中未定义Event_Name字段,需补充或修改

# Submission 模型
class Submission(models.Model):
    participant = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name="submissions")
    event = models.ForeignKey(Event, on_delete=models.SET_NULL, null=True)
    details = models.TextField(null=True, blank=False)
    id = models.UUIDField(default=uuid.uuid4, unique=True,primary_key=True, editable=False)

    def __str__(self):
        return str(self.event) + ' --- ' + str(self.participant)

视图代码

def single_event(request, pk):
    try:
        event = Event.objects.get(Event_ID=pk)
        submitted = Submission.objects.filter(event=event)
        submitted = list(submitted.values('participant','details'))
    except:
        return render(request, 'events/single-event.html', {"success":True,}, status=200)
    context = {'events':Event.objects.filter(Event_ID=pk), 'event':event, 'submitted':submitted}
    return render(request, 'events/single-event.html', context)

模板代码(single-event.html)

{% for event in events %}
    {% for user in event.Event_participants.all %}
    <tr>
        <td>{{ user.profile.title }}</td>
        <td>{{ user.first_name }} {{ user.last_name }}</td>
        <td>{{ ??????????? }}</td>  <!-- 此处需显示Submission模型中的details字段 -->
    </tr>
    {% endfor %}
{% endfor %}

解决方案

方案一:利用模型关联直接获取(推荐)

Submission模型已给participant字段设置related_name="submissions",可通过用户对象直接关联到对应报名记录,同时优化视图避免N+1查询。

修改视图

from django.db.models import Prefetch

def single_event(request, pk):
    try:
        # 预加载参与者对应的当前活动报名记录
        event = Event.objects.prefetch_related(
            Prefetch(
                'Event_participants__submissions',
                queryset=Submission.objects.filter(event__Event_ID=pk),
                to_attr='event_submissions'
            )
        ).get(Event_ID=pk)
    except Event.DoesNotExist:
        return render(request, 'events/single-event.html', {"success":True,}, status=200)
    # 无需传递events,直接使用单个event对象即可
    context = {'event': event}
    return render(request, 'events/single-event.html', context)

修改模板

{% for user in event.Event_participants.all %}
<tr>
    <td>{{ user.profile.title }}</td>
    <td>{{ user.first_name }} {{ user.last_name }}</td>
    <!-- 通过预加载的event_submissions获取详情,处理未提交情况 -->
    <td>{{ user.event_submissions.0.details|default:"未提交报名详情" }}</td>
</tr>
{% endfor %}

方案二:将报名记录转为字典映射

把Submission记录转为以用户ID为键的字典,模板中通过用户ID匹配详情。

修改视图

def single_event(request, pk):
    try:
        event = Event.objects.get(Event_ID=pk)
        submitted = Submission.objects.filter(event=event)
        # 构建用户ID到详情的映射字典
        submission_map = {sub.participant_id: sub.details for sub in submitted}
    except Event.DoesNotExist:
        return render(request, 'events/single-event.html', {"success":True,}, status=200)
    context = {'event': event, 'submission_map': submission_map}
    return render(request, 'events/single-event.html', context)

修改模板

首先需要自定义模板过滤器,在app的templatetags目录下创建custom_filters.py:

from django import template

register = template.Library()

@register.filter
def get_item(dictionary, key):
    return dictionary.get(key)

然后在模板中加载过滤器并使用:

{% load custom_filters %}

{% for user in event.Event_participants.all %}
<tr>
    <td>{{ user.profile.title }}</td>
    <td>{{ user.first_name }} {{ user.last_name }}</td>
    <td>{{ submission_map|get_item:user.id|default:"未提交报名详情" }}</td>
</tr>
{% endfor %}

注意事项

  • 原Event模型的__str__方法返回self.Event_Name,但模型中未定义该字段,需补充字段或修改返回值,避免报错。
  • 方案一使用Prefetch预加载数据,能有效减少数据库查询次数,提升页面性能,优先推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 04:53:20