Reputation: 1315
I'm trying to render a Django form on every page of my Wagtail site in a jQuery slideout box. I've created a template tag that is currently rendering the box, but the form is not showing up. I'm thinking that I'm incorrectly passing the form variable. My template tag file looks like this:
from django import template
from django.shortcuts import render, redirect
from django.template.loader import get_template
from django.core.mail import EmailMessage
from django.template import Context
from .forms import DemoForm
register = template.Library()
@register.inclusion_tag('demo_form.html')
def book_a_demo(request):
form = DemoForm
if request.method == 'POST':
demo_form = form(data=request.POST)
if demo_form.is_valid():
contact_name = request.POST.get('name', '')
company_name = request.POST.get('company', '')
contact_email = request.POST.get('email', '')
contact_phone = request.POST.get('phone', '')
# Email the profile with the
# contact information
template = get_template('contact_template.txt')
context = Context({
'contact_name': contact_name,
'company_name': company_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
})
content = template.render(context)
email = EmailMessage(
"Request to Book a Demo",
content,
"domain" +'',
['[email protected]'],
headers = {'Reply-To': contact_email }
)
email.send()
return render(request, 'demo_form_landing.html')
return render(request, 'demo_form.html', {'form': form})
demo_form.html looks like this:
{% load static %}
<div id="feedback">
<div id="feedback-tab">Book a Demo</div>
<div id="feedback-form" style='display:block;' class="col-xs-4 col-md-4 panel panel-default">
<form role="form" action="" method="post" class="form panel-body">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-primary pull-right" type="submit">Send</button>
</form>
</div>
</div>
My form looks like this:
from django import forms
class DemoForm(forms.Form):
name = forms.CharField(initial='Your Name', max_length=100)
company = forms.CharField(initial='Company Name', max_length=100)
email = forms.EmailField(initial='Email')
phone = forms.CharField(initial='Phone Number', max_length=100)
The template tag I'm using to try to render it in the main base.html is {% book_a_demo request %}
Any idea what I'm doing wrong? I don't get any errors; it just doesn't appear. I've been stuck on this for hours and it's driving me crazy.
Upvotes: 3
Views: 1863
Reputation: 983
What is returned when the request is not a POST or is_valid() is false? I typically use a pattern like this (note the changes at the end):
from .forms import DemoForm
register = template.Library()
@register.inclusion_tag('demo_form.html')
def book_a_demo(request):
form = DemoForm
if request.method == 'POST':
demo_form = form(data=request.POST)
if demo_form.is_valid():
contact_name = request.POST.get('name', '')
company_name = request.POST.get('company', '')
contact_email = request.POST.get('email', '')
contact_phone = request.POST.get('phone', '')
# Email the profile with the
# contact information
template = get_template('contact_template.txt')
context = Context({
'contact_name': contact_name,
'company_name': company_name,
'contact_email': contact_email,
'contact_phone': contact_phone,
})
content = template.render(context)
email = EmailMessage(
"Request to Book a Demo",
content,
"domain" +'',
['[email protected]'],
headers = {'Reply-To': contact_email }
)
email.send()
return render(request, 'demo_form_landing.html')
else:
demo_form = form()
return render(request, 'demo_form.html', {'form': demo_form})
Upvotes: 0
Reputation: 25292
When using inclusion_tag
, you shouldn't call render
yourself. You should return the context dictionary (for example: return {'form': form}
) - Django will then take care of rendering the template you named in the @register.inclusion_tag('demo_form.html')
declaration.
I would advise against trying to handle the if request.method == 'POST':
logic within the tag, as that will be triggered any time any page on your site is rendered in response to a POST request - regardless of whether the POST request had anything to do with your DemoForm. Instead, you should set up a Django view to handle those form submissions, and put the URL to that view in the form's action
attribute.
Upvotes: 4