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

Django模板表单提交按钮失效问题排查与解决请求

Django表单提交按钮无响应问题排查与解决

问题背景

使用Django 3.0和Python 3.7开发时,模板中的表单提交按钮点击后无响应,未触发任何后端操作。以下是相关代码及排查、解决步骤:

相关代码片段

views.py(sendmail视图)

def sendmail(request):
    company={}
    form = JobEmailDataForm()
    client = request.user.client
    client_id = request.user.client.id
    email_data = JobEmailData.objects.filter(client_id=client)
    for i in email_data:
        reminderstatus = i.reminder_status
        bookingstatus = i.booking_today_status
        purchasing_officer = i.purchasing_officer
    bookedby = request.user
    
    client_data = Client.objects.filter(id=client_id)
  
    for val in client_data:
      
        company['name']=val.name
        company['phone']=val.phone
        company['email']=val.email
        company['replay_to_email']=val.replay_to_email or ''
        company['website']=val.website
        company['logo'] = val.logo_url
    company['address'] = get_client_address(client)
    return render(request, 'core/job_email_form_1.html', locals())

forms.py(JobEmailDataForm表单类)

class JobEmailDataForm(forms.Form):
    name       = forms.CharField(max_length=100, label='Company Name', widget=forms.TextInput(attrs={'class':'input-xlarge'}))
    address    = forms.CharField(max_length=256, label='Company Address', widget=forms.TextInput(attrs={'class':'input-xlarge'}))
    phone      = forms.CharField(max_length=100, label='Company Phone', widget=Html5TelephoneInput(attrs={'class':'input-xlarge'}))
    website    = forms.URLField(max_length=100, label='Company Website', required=False, widget=forms.TextInput(attrs={'class':'input-xlarge'}))
    email      = forms.EmailField(label='Company Email', widget=Html5EmailInput(attrs={'class':'input-xlarge'}))
    replay_to_email = forms.EmailField(label='Send from Email (Optional)', required=False, widget=Html5EmailInput(attrs={'class':'input-xlarge'}))
    purchasing_officer = forms.EmailField(label='Purchasing Officer Email', required=False, widget=Html5EmailInput(attrs={'class':'input-xlarge'}))
    logo       = forms.ImageField(label='Image', required=False)
    confirmation = forms.CharField(max_length=256, label='Additional Booking Confirmation Message', widget=forms.Textarea)
    amendments = forms.CharField(max_length=256, label='Additional Booking Amendments Message', widget=forms.Textarea)
    cancellation = forms.CharField(max_length=256, label='Additional Booking Cancellation Message', widget=forms.Textarea)
    booking_today = forms.CharField(max_length=256, label='Additional Booking today Message', widget=forms.Textarea)
    reminder = forms.CharField(max_length=256, label='Additional Booking Reminders Message', widget=forms.Textarea)
    
    reminder_status   = forms.ChoiceField(choices=REMINDER_CHOICES,label='Reminders Message Settings',)
    booking_today_status   = forms.ChoiceField(choices=REMINDER_CHOICES,label='Booking Today Message Settings',)
    class Meta:
        widgets = {
            "confirmation": forms.TextInput,
        }
        fields = ['name', 'address', 'phone', 'website','email', 'replay_to_email' , 'logo','confirmation','amendments','cancellation','reminder','is_email_customer','is_email_user','reminder_status']

job_email.html模板

<div class="row">
    <div class="span6 offset1">
        <!-- START non-filtered -->
        <form method="post" enctype="multipart/form-data"  action="/saveemaildata/">
            {% csrf_token %}
            {% for hidden in form.hidden_fields %}
                {{ hidden }}
            {% endfor %}
            <fieldset class="add">
                <br><br>
                {% for field in form.visible_fields %}
                <div class="control-group">
                    <label class="control-label pull-left" for="{{ field.auto_id }}">{{ field.label }}</label>
                    <div class="controls" style="margin-left: 0px;">
                        {{ field }} {% if field.label == 'Send from Email (Optional)' %}{% if client.email_validated_status == 'processed' or client.email_validated_status == 'Approved by client' %} Processed <a href="#EmailValidateModal" data-toggle="modal">Check now</a> {% elif client.email_validated_status == 'Validated' %} Validated<a href="#EmailValidateModal" data-toggle="modal">Check now</a> {% elif client.email_validated_status == 'Pending' %} Validate - <a href="#EmailValidateModal" data-toggle="modal">Check how</a> {% endif  %}{% endif  %}
                    </div> 
                    <p>{{ field.help_text }}</p>
                </div>
                {% endfor %}
            </fieldset>
            <div id="form-buttons-container" class="form-actions">
                <div class="controls">
                    <input type="submit" class="btn btn-inverse" value="Update JobEmails">
                    <a class="btn btn-default" href="{% url "roles_list" %}">Cancel</a>
                    {% if role %}
                    <a class="btn btn-danger" href="{% url "roles_delete" role.pk %}">Delete role</a>
                    {% endif %}
                </div> <!--/form-actions-->
            </div>
        </form>
        .....
        .....
        .....
    </div> <!-- /row -->

urls.py配置

re_path(r'^saveemaildata/$',savejob,name='save_email_data'),

savejob处理视图

def savejob(request):
    messages = []
    client = request.user.client
    if request.POST:
        companyName = request.POST['name']
        companyAddress = request.POST['address']
        companyPhone = request.POST['phone']
        companyWebsite = request.POST['website']
        companyEmail = request.POST['email']
        replay_to_email = request.POST['replay_to_email']
        purchasing_officer = request.POST['purchasing_officer']
        Confirmation = request.POST['confirmation']
        Amendments = request.POST['amendments']
        Cancellation = request.POST['cancellation']
        Reminder = request.POST['reminder']
        Bookingtoday = request.POST['booking_today']
        reminder_status = request.POST['reminder_status']
        booking_today_status = request.POST['booking_today_status']
        client_id = ClientUser.objects.filter(id=request.user.id)[0].client_id
        doc = Client.objects.get(id=client_id)
        errors = []

        import sys, traceback

        if replay_to_email:
            if doc.replay_to_email != replay_to_email:
                doc.email_validated_status = 'Pending'
                send_email_validate.delay(request.user, 1)
        doc.name = companyName
        doc.replay_to_email = replay_to_email
        doc.email = companyEmail
        doc.phone = companyPhone
        doc.website = companyWebsite

        if 'logo' in request.FILES:
            doc.logo_url = request.FILES['logo']
            print("DOC LOGO URL IS",doc.logo_url)
            doc.logo_url.storage = S3Boto3Storage(bucket_name='lightdegree')
            print("DOC LOGO URLLL",doc.logo_url.storage)
        else:
            errors.append("There is no document specified")
    doc.save()
    template = 'core/savejob.html'
    objclient =  Client.objects.get(name=companyName,email=companyEmail)
    clientid = objclient.id
    email_data = JobEmailData.objects.filter(client_id=clientid)
    if not email_data:
        objemail = JobEmailData(name = companyName,phone=companyPhone,
            website=companyWebsite,client_id=clientid,
            address=companyAddress,
            confirmation=Confirmation,amendments=Amendments,
            cancellation=Cancellation,reminder=Reminder,booking_today=Bookingtoday,
            purchasing_officer=purchasing_officer,reminder_status=reminder_status,booking_today_status=booking_today_status)
        objemail.save()
    else:        
        objemail = JobEmailData.objects.filter(client_id=clientid).update(name = companyName,phone=companyPhone,
            website=companyWebsite,
            address=companyAddress,
            confirmation=Confirmation,amendments=Amendments,
            cancellation=Cancellation,reminder=Reminder,booking_today=Bookingtoday,
            purchasing_officer=purchasing_officer,reminder_status=reminder_status,booking_today_status=booking_today_status)
    messages.append('Job emails successfully updated')
    return HttpResponseRedirect('/admin/job_emails/') 

排查出的问题及解决方法

1. 表单字段定义与Meta配置不匹配

问题:JobEmailDataForm的Meta.fields中包含is_email_customer和is_email_user两个字段,但表单类中未定义这两个字段,会导致表单初始化时抛出异常,模板渲染失败,表单无法正常交互。

解决:修改forms.py中的Meta.fields,移除未定义的字段,确保与表单类中实际定义的字段一致:

class Meta:
    widgets = {
        "confirmation": forms.TextInput,
    }
    fields = ['name', 'address', 'phone', 'website','email', 'replay_to_email' , 'logo','confirmation','amendments','cancellation','reminder','reminder_status', 'booking_today_status']

2. 表单未绑定初始化数据

问题:sendmail视图中创建JobEmailDataForm时未传入从数据库获取的company和email_data数据,表单为空且未填充用户已有信息,若存在必填项未填写,浏览器的HTML5验证会阻止表单提交。

解决:将获取到的用户数据作为initial参数传给表单,同时补充email_data中的字段:

def sendmail(request):
    client = request.user.client
    client_id = request.user.client.id
    email_data = JobEmailData.objects.filter(client_id=client).first()
    # 初始化表单数据
    initial_data = {}
    # 填充client数据
    client_data = Client.objects.get(id=client_id)
    initial_data['name'] = client_data.name
    initial_data['phone'] = client_data.phone
    initial_data['email'] = client_data.email
    initial_data['replay_to_email'] = client_data.replay_to_email or ''
    initial_data['website'] = client_data.website
    initial_data['address'] = get_client_address(client)
    # 填充email_data数据
    if email_data:
        initial_data['reminder_status'] = email_data.reminder_status
        initial_data['booking_today_status'] = email_data.booking_today_status
        initial_data['purchasing_officer'] = email_data.purchasing_officer
        initial_data['confirmation'] = email_data.confirmation
        initial_data['amendments'] = email_data.amendments
        initial_data['cancellation'] = email_data.cancellation
        initial_data['booking_today'] = email_data.booking_today
        initial_data['reminder'] = email_data.reminder
    # 创建绑定初始数据的表单
    form = JobEmailDataForm(initial=initial_data)
    bookedby = request.user
    return render(request, 'core/job_email_form_1.html', locals())

3. savejob视图逻辑错误

问题:doc.save()及后续处理逻辑位于if request.POST:块外部,当以GET请求访问/saveemaildata/时,doc变量未定义,会抛出NameError导致服务器500错误,POST请求提交后也可能因逻辑执行顺序问题报错。

解决:将所有处理逻辑移至if request.POST:块内部,确保只有POST请求时才执行数据保存操作:

def savejob(request):
    messages = []
    client = request.user.client
    if request.POST:
        companyName = request.POST['name']
        companyAddress = request.POST['address']
        companyPhone = request.POST['phone']
        companyWebsite = request.POST['website']
        companyEmail = request.POST['email']
        replay_to_email = request.POST['replay_to_email']
        purchasing_officer = request.POST['purchasing_officer']
        Confirmation = request.POST['confirmation']
        Amendments = request.POST['amendments']
        Cancellation = request.POST['cancellation']
        Reminder = request.POST['reminder']
        Bookingtoday = request.POST['booking_today']
        reminder_status = request.POST['reminder_status']
        booking_today_status = request.POST['booking_today_status']
        client_id = ClientUser.objects.filter(id=request.user.id)[0].client_id
        doc = Client.objects.get(id=client_id)
        errors = []

        if replay_to_email:
            if doc.replay_to_email != replay_to_email:
                doc.email_validated_status = 'Pending'
                send_email_validate.delay(request.user, 1)
        doc.name = companyName
        doc.replay_to_email = replay_to_email
        doc.email = companyEmail
        doc.phone = companyPhone
        doc.website = companyWebsite

        if 'logo' in request.FILES:
            doc.logo_url = request.FILES['logo']
            doc.logo_url.storage = S3Boto3Storage(bucket_name='lightdegree')
        
        doc.save()
        objclient = Client.objects.get(id=client_id)
        clientid = objclient.id
        email_data = JobEmailData.objects.filter(client_id=clientid)
        if not email_data:
            objemail = JobEmailData(name=companyName, phone=companyPhone,
                website=companyWebsite, client_id=clientid,
                address=companyAddress,
                confirmation=Confirmation, amendments=Amendments,
                cancellation=Cancellation, reminder=Reminder, booking_today=Bookingtoday,
                purchasing_officer=purchasing_officer, reminder_status=reminder_status, booking_today_status=booking_today_status)
            objemail.save()
        else:        
            JobEmailData.objects.filter(client_id=clientid).update(name=companyName, phone=companyPhone,
                website=companyWebsite,
                address=companyAddress,
                confirmation=Confirmation, amendments=Amendments,
                cancellation=Cancellation, reminder=Reminder, booking_today=Bookingtoday,
                purchasing_officer=purchasing_officer, reminder_status=reminder_status, booking_today_status=booking_today_status)
        messages.append('Job emails successfully updated')
        return HttpResponseRedirect('/admin/job_emails/')
    # 非POST请求返回表单页面或其他提示
    return HttpResponseRedirect('/path/to/email/form/')

4. 表单action硬编码URL

问题:模板中表单action使用硬编码的/saveemaildata/,若URL配置变更会导致提交失败,且不符合Django最佳实践。

解决:使用Django的URL反向解析生成action地址:

<form method="post" enctype="multipart/form-data" action="{% url 'save_email_data' %}">

5. 前端验证或JS问题

排查:打开浏览器开发者工具(F12),查看控制台是否有JavaScript错误,检查表单字段是否有未填写的必填项(浏览器会在控制台提示或在字段旁显示错误)。

解决:修复JS错误,确保所有必填字段都有值,或根据需求调整表单字段的required属性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 18:10:30