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

Django表单传递选中元素异常:邮件发送至错误收件人

问题分析
  1. 序号匹配错误:模板使用forloop.counter(从1开始)命名表单隐藏字段和按钮,但视图中用enumerate的默认索引i(从0开始)匹配,导致无法正确获取trip_id,打印结果为None。
  2. 循环逻辑低效且易出错:遍历所有Trip对象判断按钮点击,不仅浪费资源,还可能因数据顺序不一致导致邮件发送给错误用户。

修复方案

方案一:优化逻辑(推荐)

直接从POST数据中提取点击的按钮,获取对应行程ID后查询Trip对象发送邮件,彻底避免顺序问题:

from django.shortcuts import render, get_object_or_404
from .models import Trip 
from django.core.mail import EmailMessage
from django.conf import settings 

def accept(request):
    trips = Trip.objects.all()
    z = {'aw': trips}

    if request.method == 'POST':
        # 定位被点击的操作按钮
        action_key = None
        for key in request.POST.keys():
            if key.startswith('accept_') or key.startswith('refuse_'):
                action_key = key
                break
        
        if action_key:
            # 提取行程序号与ID
            trip_num = action_key.split('_')[1]
            trip_id = request.POST.get(f'trip_id_{trip_num}')
            
            if trip_id:
                # 获取目标行程对象
                trip = get_object_or_404(Trip, id=trip_id)
                # 组装邮件内容
                if action_key.startswith('accept_'):
                    subject = 'Trip accepted'
                    message = 'Hi there! Your trip has been accepted.'
                else:
                    subject = 'Trip refused'
                    message = 'Hi there! Your trip has been refused.'
                # 发送邮件
                email_msg = EmailMessage(
                    subject,
                    message,
                    settings.EMAIL_HOST_USER,
                    [trip.owner_email],
                )
                email_msg.fail_silently = True
                email_msg.send()
                print(f"trip_id = {trip_id}")

    return render(request, 'system/accept.html', z)

模板代码保持不变即可,此方案通过trip_id直接查询目标行程,完全不受数据顺序影响。

方案二:仅修正序号匹配(不推荐)

如果不想大幅修改逻辑,只需让视图的序号从1开始,匹配模板的forloop.counter:

from django.shortcuts import render
from .models import Trip 
from django.core.mail import EmailMessage
from django.conf import settings 

def accept(request):
    trips = Trip.objects.all()
    z = {'aw': trips}

    if request.method == 'POST':
        # 让enumerate索引从1开始,匹配模板的forloop.counter
        for i, trip in enumerate(trips, start=1):
            trip_id = request.POST.get(f'trip_id_{i}') 
            print(f"trip_id = {trip_id}")

            if f'accept_{i}' in request.POST:
                email_msg = EmailMessage(
                    'Trip accepted',
                    'Hi there! Your trip has been accepted.',
                    settings.EMAIL_HOST_USER,
                    [trip.owner_email],
                )
                email_msg.fail_silently = True
                email_msg.send() 
            elif f'refuse_{i}' in request.POST:
                email_msg = EmailMessage(
                    'Trip refused',
                    'Hi there! Your trip has been refused.',
                    settings.EMAIL_HOST_USER,
                    [trip.owner_email],
                )
                email_msg.fail_silently = True
                email_msg.send()

    return render(request, 'system/accept.html', z)

原代码出错原因
  • 模板生成的字段名是trip_id_1、trip_id_2,但视图中查找的是trip_id_0、trip_id_1,完全不匹配,导致trip_id始终为None。
  • 遍历所有Trip时,若数据库存储顺序与页面渲染顺序不一致,就会出现点击第二个行程却给第一个行程所有者发邮件的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:40:31