Home > Blockchain >  Django form doesn't display
Django form doesn't display

Time:02-17

I'm trying to develop a simple Django app of a contact form and a thank you page, but I can't get the actual form to display at /contact/contact; all I see is the submit button.

enter image description here

I'm not using Django 'admin' at all; no database, either. I'm working on locolhost using python manage.py runserver

Why does my form not display?

Do I need a model of the form?

This is the directory structure:

enter image description here

/contact/contact/urls.py

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

from django.urls import include
urlpatterns  = [
    path('contact/', include('contactform.urls')),
]

from django.conf import settings
from django.conf.urls.static import static

urlpatterns  = static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

/contact/contactform/urls.py

from django.urls import path
from . import views

app_name = 'contactform'

urlpatterns = [
    path('thanks/', views.thanks, name='thanks'),
    path('contact/', views.contact, name='contact'),
]

/contact/contactform/views.py

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404

from contactform.forms import ContactForm
from contact.settings import EMAIL_HOST_USER, EMAIL_PORT, EMAIL_HOST_PASSWORD, EMAIL_HOST

def thanks(request):
    return render(request, 'thanks.html', {})

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            form_data = form.cleaned_data
            msg = MIMEMultipart()
            msg['From'] = EMAIL_HOST_USER
            msg['To'] = EMAIL_HOST_USER
            msg['Subject'] = f'Personal site: {form_data["subject"]}'
            message = f'Name: {form_data["name"]}\n' \
                      f'Email address: {form_data["email_address"]}\n\n' \
                      f'{form_data["message"]}'
            msg.attach(MIMEText(message))
            with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server:
                server.ehlo()
                server.starttls()
                server.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD)
                server.sendmail(EMAIL_HOST_USER, EMAIL_HOST_USER, msg.as_string())
            return HttpResponseRedirect('/thanks')
    else:
        form = ContactForm()

    return render(request, 'contact.html')

/contact/contactform/models.py

from django.urls import reverse

/contact/contactform/apps.py

from django.apps import AppConfig

class ContactformConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'contactform'

/contact/contactform/forms.py

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(required=True, widget=forms.TextInput(
        attrs={'class': 'form-control', 'maxlength': '100'}
    ))
    email_address = forms.EmailField(required=True, widget=forms.EmailInput(
        attrs={'class': 'form-control', 'maxlength': '100'}
    ))
    subject = forms.CharField(required=True, widget=forms.TextInput(
        attrs={'class': 'form-control', 'maxlength': '100'}
    ))
    message = forms.CharField(required=True, widget=forms.Textarea(
        attrs={'class': 'form-control', 'maxlength': '1000', 'rows': 8}
    ))

/contact/contactform/templates/contact.html

<h2>Form</h2>
    <form action="/contact/" method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Send</button>
    </form>

CodePudding user response:

The form does not display as you are not passing it into your template. You can do this instead in the contact view:

return render(request, 'contact.html', {
     'form': form
})

EDIT:
If you are getting 'return' outside function error, you can do this in your contact view.

def contact(request):
    form = ContactForm() # Before if condition

You can remove the else condition.

EDIT 2:
This should be your contact view.

def contact(request):
    form = ContactForm()
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            form_data = form.cleaned_data
            msg = MIMEMultipart()
            msg['From'] = EMAIL_HOST_USER
            msg['To'] = EMAIL_HOST_USER
            msg['Subject'] = f'Personal site {form_data["subject"]}'
            message = f'Name: {form_data["name"]}\n' \
                  f'Email address: {form_data["email_address"]}\n\n' \
                  f'{form_data["message"]}'
            msg.attach(MIMEText(message))
            with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server:
                server.ehlo()
                server.starttls()
                server.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD)
                server.sendmail(EMAIL_HOST_USER, EMAIL_HOST_USER, msg.as_string())
            return HttpResponseRedirect('/thanks')
        else:
            return HttpResponseRedirect(reverse('contactform:contact'))

    return render(request, 'contact.html')

CodePudding user response:

Your Django form doesn't display because you are not passing the form to your html template. you have to pass it.

return render(request, 'contact.html','form':form)
  • Related