I'm building a homepage that includes a contact-us form. This contact-us form element should be reusable across multiple pages, so I've used HTMX to try incorporate. However am receiving the following error, which I can't make sense of because I'm submitting POST data.
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
**
This file contains the form logic
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
**
for the form element
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
**
for the homepage
def home(request):
form = Contact_Us_Form()
return render(request, 'pages/home.html', {'form': form})
** Urls.py
**
urlpatterns = [
path("", include('dashboard.urls')), # the homepage is rendered via separate urls.py on the 'dashboard' app's urls.py
path('contactus', Contact_Us_Form, name="contact"),
]
** home.html
relevant section from homepage **
<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 <a href="https://policies.google.com/privacy">Google Privacy Policy</a> and <a href="https://policies.google.com/terms">Terms Of Service</a> apply.</p>
</div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-secondary w-20">Submit</button>
</div>
</form>
My troubleshooting process Don't understand why POST data is throwing a GET error. Also don't really understand how WSGI is coming into this picture. It looks like similar errors have been raised on SO before without resolution.
method="POST"
and action="contacts"
to override this behaviour. No successform = Contact_Us_Form(request.POST)
into form = Contact_Us_Form(data = request.POST)
. No successnetwork
inspect tab for payload and headers. Request Method = POST
and payload includes expected fields (name, sender, message content
)CSRF
references throughout the document. This is not the source of the errorYou should link the path to the view so contact_us_response
, not the form (`):Contact_Us_Form
urlpatterns = [
path(
'', include('dashboard.urls')
), # the homepage is rendered via separate urls.py on the 'dashboard' app's urls.py
path('contactus', contact_us_response, name='contact'),
]