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

Django-HTMX集成报错:'WSGIRequest'对象无'get'属性

Django + HTMX 提交联系表单触发 AttributeError 问题

错误详情

Request Method: POST
Request URL: http://localhost:8000/contactus

Django Version: 4.2.13
Python Version: 3.9.6
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'debug_toolbar',
 'accounts',
 'dashboard']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware']


Traceback (most recent call last):
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 220, in _get_response
    response = response.render()
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/utils.py", line 67, in render
    context = context or self.get_context()
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/forms.py", line 322, in get_context
    top_errors = self.non_field_errors().copy()
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/forms.py", line 358, in non_field_errors
    return self.errors.get(
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/forms.py", line 196, in errors
    self.full_clean()
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/forms.py", line 433, in full_clean
    self._clean_fields()
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/forms.py", line 440, in _clean_fields
    value = bf.initial if field.disabled else bf.data
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/boundfield.py", line 135, in data
    return self.form._widget_data_value(self.field.widget, self.html_name)
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/forms.py", line 220, in _widget_data_value
    return widget.value_from_datadict(self.data, self.files, html_name)
  File "/Users/robrobrob/Desktop/Projects/Trolleys/venv/lib/python3.9/site-packages/django/forms/widgets.py", line 297, in value_from_datadict
    return data.get(name)

Exception Type: AttributeError at /contactus
Exception Value: 'WSGIRequest' object has no attribute 'get'

相关代码文件

Forms.py

class Contact_Us_Form(forms.Form):
    name = forms.CharField(
        label="Name",
        max_length=60,
        widget=forms.TextInput(attrs={'class': 'form-control'})
    )
    sender = forms.EmailField(
        widget=forms.TextInput(attrs={'class': 'form-control'}), 
        label="Email"
    )
    message_content = forms.CharField(
        widget=forms.Textarea(attrs={'class': 'form-control'}),
        label="Your message"
    )

Views.py(表单处理视图)

def contact_us_response(request):
    if request.method == "POST":
        form = Contact_Us_Form(data=request.POST)
        if form.is_valid():
            return redirect("partials/success.html")
        else:
            return HttpResponse("Something's broke")
    elif request.method == "GET":
        form = Contact_Us_Form()
        return render(request, "partials/contact.html", {"form": form})
    else:
        form = Contact_Us_Form()
        return HttpResponse("Method not allowed", status=405)

Views.py(主页视图)

def home(request):
    form = Contact_Us_Form()
    return render(request, 'pages/home.html', {'form': form})

Urls.py

urlpatterns = [
 path("", include('dashboard.urls')), # 主页通过dashboard应用的urls.py渲染
 path('contactus', Contact_Us_Form, name="contact"),
]

home.html(主页表单代码)

<form id="contact-us-form" hx-post="{% url 'contact' %}" hx-target="#contact-us-form">
{{ form }}
<button type="submit" class="btn btn-secondary w-20" >Submit</button>
</form>

contact.html(表单片段)

<form>
    <div class="mb-3">
        <label for="name" class="form-label d-inline">Name <p class="text-secondary d-inline">*</p></label>
        {{ form.name }}
    </div>
    <div class="mb-3">
        <label for="email" class="form-label">Email <p class="text-secondary d-inline">*</p></label>
        {{ form.sender }}
    </div>
    <div class="mb-3">
        <label for="message" class="form-label">How can we help you? <p class="text-secondary d-inline">*</p></label>
        {{ form.message_content }}
        <p class="small text-secondary">We'll hold your details in accordance with our Privacy Policy. 
            This site is protected by reCAPTCHA and the Google Privacy Policy and Terms Of Service apply.</p>
    </div>
    <div class="d-flex justify-content-end">
    <button type="submit" class="btn btn-secondary w-20">Submit</button>
    </div>
</form>

排查过程

  • 在views.py中添加GET场景分支处理
  • 尝试添加/移除表单的method="POST"和action="contacts"属性,无效
  • 尝试将form = Contact_Us_Form(request.POST)改为form = Contact_Us_Form(data = request.POST),无效
  • 检查网络请求载荷与头信息,确认请求方法为POST且包含预期字段
  • 尝试添加/移除CSRF引用,确认非CSRF问题

解决方案

1. 修复URL路由的核心错误

问题出在Urls.py中,你把表单类Contact_Us_Form直接绑定到了路由上,而不是对应的视图函数contact_us_response。Django路由需要接收视图函数(或类视图),当你传入表单类时,Django会把请求对象request当作表单的初始化参数传入,导致表单内部的self.data变成了WSGIRequest对象,而不是预期的POST数据字典,最终调用data.get()时触发AttributeError。

修改Urls.py:

# 先确保导入了视图函数
from .views import contact_us_response

urlpatterns = [
 path("", include('dashboard.urls')),
 path('contactus', contact_us_response, name="contact"), # 替换为视图函数
]

2. 修正表单提交后的跳转逻辑

当前视图中redirect("partials/success.html")是错误的,redirect()接收的是URL名称或者完整URL,不是模板路径。你需要先为成功页面添加路由,或者返回一个HTMX能替换的成功片段。

示例:创建success.html片段,然后返回渲染后的内容:

if form.is_valid():
    # 这里可以添加表单数据处理逻辑,比如发送邮件等
    return render(request, "partials/success.html")

3. 完善模板中的CSRF防护

HTMX需要CSRF令牌才能正常提交POST请求,确保模板中包含CSRF令牌:
在home.html的表单内添加:

{% csrf_token %}

修改后的表单:

<form id="contact-us-form" hx-post="{% url 'contact' %}" hx-target="#contact-us-form">
    {% csrf_token %}
    {{ form }}
    <button type="submit" class="btn btn-secondary w-20">Submit</button>
</form>

4. 优化表单验证失败的响应

当表单验证失败时,应该返回带错误信息的表单片段,而不是简单的文本,这样HTMX可以替换原表单显示错误:

if form.is_valid():
    return render(request, "partials/success.html")
else:
    return render(request, "partials/contact.html", {"form": form})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:14:55