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

Django注册页面出现500内部服务器错误,如何修复is_ajax属性问题?

Django注册页面500内部服务器错误:修复is_ajax相关问题

问题描述

注册页面触发500内部服务器错误,排查后锁定views.py中is_ajax属性相关逻辑存在问题,相关代码如下:

views.py

class SignUpView(AjaxFormMixin, FormView):
    '''
    集成自定义Mixin的通用FormView,用于带reCAPTCHA验证的用户注册
    '''

    template_name = "users/sign_up.html"
    form_class = UserForm
    success_url = "/"

    # 向上下文传入reCAPTCHA公钥
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["recaptcha_site_key"] = settings.RECAPTCHA_PUBLIC_KEY
        return context

    # 重写Mixin逻辑,处理reCAPTCHA验证并保存分数
    def form_valid(self, form):
        response = super(AjaxFormMixin, self).form_valid(form)
        if self.request.is_ajax():
            token = form.cleaned_data.get('token')
            captcha = reCAPTCHAValidation(token)
            if captcha["success"]:
                obj = form.save()
                obj.email = obj.username
                obj.save()
                up = obj.userprofile
                up.captcha_score = float(captcha["score"])
                up.save()

                login(self.request, obj, backend='django.contrib.auth.backends.ModelBackend')

                # 设置成功结果和提示信息
                result = "Success"
                message = "Thank you for signing up"

            data = {'result': result, 'message': message}
            return JsonResponse(data)

        return response

urls.py

from django.urls import path
from . import views

app_name = "users"
urlpatterns = [
    path('', views.AccountView.as_view(), name="account"),
    path('profile', views.profile_view, name="profile"),
    path('sign-up', views.SignUpView.as_view(), name="sign-up"),
    path('sign-in', views.SignInView.as_view(), name="sign-in"),
    path('sign-out', views.sign_out, name="sign-out"),
]

sign_up.html及base.html

{% extends 'base.html' %}
{% load static %}

{% block extend_head %}
<script src='https://www.google.com/recaptcha/api.js?render={{recaptcha_site_key}}'></script>
{% endblock %}

{% block content %}
<h3>Django Google API 课程 - 注册</h3>

<div class="container">
  <form id="signupform" method="POST" action="/sign-up">
    {% csrf_token %}

    <label for="first_name">名字</label>
    {{form.first_name}}

    <label for="last_name">姓氏</label>
    {{form.last_name}}

    <label for="username">用户名</label>
    {{form.username}}

    <label for="password1">密码</label>
    {{form.password1}}

    <label for="password2">确认密码</label>
    {{form.password2}}

    {{form.token}}

    <label class="check-container">显示密码
     <input type="checkbox" onclick="showPword()">
     <span class="checkmark"></span>
    </label>

    <button type="submit">注册</button>
  </form>
</div>
{% endblock %}

{% block extend_footer %}
<script type="text/javascript">
  // 创建可在main.js中使用的变量
  var recaptcha_site_key = '{{recaptcha_site_key|safe}}'
</script>
{% endblock %}


<!-- base.html -->
{% load static %}

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="{% static 'main.css' %}"></link>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.css" integrity="sha512-3pIirOrwegjM6erE5gPSwkUzO+3cTjpnV9lexlNZqvupR64iZBnOOTiiLPb9M36zpMScbmUNIcHUqKD47M719g==" crossorigin="anonymous" referrerpolicy="no-referrer" />

  {% block extend_head %}
  {% endblock %}
</head>
<body>
  {% include 'partials/nav.html' %}
  <div class="div-container">
    {% include 'partials/logo.html' %}
    {% block content %}
    {% endblock %}
  </div>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js" integrity="sha512-VEd+nq25CkR676O+pLBnDW09R7VQX9Mdiij052gVCp5yVH3jGtH70Ho/UUv4mJDsEdTvqRCFZg0NKGiojGnUCw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  {% block extend_footer %}
  {% endblock %}
  <script src="{% static 'main.js' %}"></script>
</body>
</html>

修复方案

1. 替换弃用的is_ajax()方法

Django 3.1及以上版本已弃用request.is_ajax(),需手动检查请求头判断是否为AJAX请求:

# 替换原有的if self.request.is_ajax():
if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest':

2. 修复未定义变量的报错

当前代码中,如果captcha["success"]为False,result和message变量未初始化就被赋值,会直接抛出NameError,这是500错误的核心诱因之一,修改后代码如下:

def form_valid(self, form):
    response = super(AjaxFormMixin, self).form_valid(form)
    # 替换is_ajax判断逻辑
    if self.request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        token = form.cleaned_data.get('token')
        captcha = reCAPTCHAValidation(token)
        # 初始化默认结果
        result = "Error"
        message = "验证失败,请重试"
        if captcha["success"]:
            obj = form.save()
            obj.email = obj.username
            obj.save()
            up = obj.userprofile
            up.captcha_score = float(captcha["score"])
            up.save()

            login(self.request, obj, backend='django.contrib.auth.backends.ModelBackend')

            # 设置成功结果和提示信息
            result = "Success"
            message = "感谢注册"

        data = {'result': result, 'message': message}
        return JsonResponse(data)

    return response

3. 确保前端以AJAX方式提交表单

当前HTML表单为普通同步提交,不会触发后端的AJAX逻辑,需在main.js中添加AJAX提交代码:

$(document).ready(function() {
    $('#signupform').submit(function(e) {
        e.preventDefault(); // 阻止普通表单提交
        const csrfToken = $('input[name="csrfmiddlewaretoken"]').val();
        const formData = $(this).serialize();
        
        // 获取reCAPTCHA令牌并发送请求
        grecaptcha.ready(function() {
            grecaptcha.execute(recaptcha_site_key, {action: 'signup'}).then(function(token) {
                formData += '&token=' + token;
                $.ajax({
                    url: '/sign-up',
                    type: 'POST',
                    headers: {
                        'X-Requested-With': 'XMLHttpRequest' // 手动标记AJAX请求
                    },
                    data: formData,
                    success: function(response) {
                        response.result === 'Success' 
                            ? (toastr.success(response.message), window.location.href='/')
                            : toastr.error(response.message);
                    },
                    error: function() {
                        toastr.error('服务器错误,请稍后重试');
                    }
                });
            });
        });
    });
});

4. 查看详细错误日志

开发环境下开启Django的DEBUG模式,直接查看500错误的完整栈信息,确认是否存在其他潜在问题(比如reCAPTCHAValidation函数报错、userprofile关联对象未创建等)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:09:55