Grant Bartel
Grant Bartel

Reputation: 363

Django contact form on homepage

I need to embed a contact form at the bottom of my homepage, which is a single page application. I followed several tutorials on how to create my own contact form on another page (e.g., myportfolio.com/contact) which were successful. Unfortunately I haven't been able to adapt those results or find other tutorials on how to make that contact form visible and functional on the same page all of my other model data is displayed (e.g., myportfolio.com).

I followed this tutorial: https://atsoftware.de/2015/02/django-contact-form-full-tutorial-custom-example-in-django-1-7. I've only created one application.

I feel like this should be a very common thing to want to do, which makes me think I'm overlooking something glaringly obvious.

views.py in application

from django.views.generic import TemplateView
from portfolio.models import Experience

class HomePage(TemplateView):
    template_name = 'portfolio/base.html'

    def get_context_data(self, *args, **kwargs):
        context = super(HomePage, self).get_context_data(*args, **kwargs)
        context['experience_list'] = Experience.objects.order_by('-start_date')

        return context

contact_form.html

{% extends 'portfolio/base.html' %}

{% block contact %}

  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit">
  </form>

{% endblock %}

Now contact_form.html goes into the portfolio/base.html like this:

base.html

{# {% include "contact_form/contact_form.html" %}#}
{% block contact %}{% endblock %}

In this scenario, nothing shows up. However, if I comment out the second line and remove the comments from the first line, the submit button appears.

Now I realize I'm assuming django-contact-form is going to pick up this form and know what to do with it like when it was accessible in the myportflio.com/contact scenario. However, I know that there used to be a reference to /contact via the urls.py file before, but in the case of embedding into the base.html file, there is not longer a reference.

Can I add the form some way in the HompePage view similar to adding model data to the context?

Upvotes: 1

Views: 2134

Answers (2)

Ken
Ken

Reputation: 45

The way I solved this in my view.py is:

    from contact_form.forms import ContactForm

def index(request):
    if request.method == 'POST':
        form = ContactForm(request.POST or None, request=request)
        if form.is_valid():  # checking if the form input is valid
            form.save()

    return render(request, 'myapp/index.html')

It is working for me with django-contact-form 1.8.2 and django 3.0.8. Anyways, I have opened a ticket in the project repo.

Upvotes: 0

hansTheFranz
hansTheFranz

Reputation: 2580

the tutorial you are following is not really up to date (its written in 1.7). So what you usually do in views.py (and what is missing in your function) is declaring the form.

I show you how I would do it, all that is a bit different from your code, but in my opinion more clear to understand and that is like the standard way.

from appName.forms import formName #dont forget to import the form
from django.views.generic import TemplateView
from portfolio.models import Experience


def HomePage(request):
  form = formName(request.POST or None) #here you tell django what form you are talking about
  if form.is_valid(): #checking if the form input is valid
    .... 
    form.save()
    #messages.success(request, 'form was posted') #this is optional but good for the user
  context = {
    'form': form,   #here you are passing the variable "form" to the template so you can use it like "{{form.as_p}}"
    'experience_list' = Experience.objects.order_by('-start_date')
    #other context variables
    }
  return render(request, "appName/MainPage.html", context)

your urls.py in the App would look like:

urlpatterns = [
  url(r'mainPage',views.HomePage, name='HomePage'), 
 ]

if you want to keep everything how it is try this:

def get_context_data(self, *args, **kwargs):
    context = super(HomePage, self).get_context_data(*args, **kwargs)
    context['experience_list'] = Experience.objects.order_by('-start_date') #maybe you have to put a "," here but I'm not sure
    context['form'] = formName

    return context

but I'm not sure how to make the validation like this in a generic TemplateView. Anyway since you declared the "form" variable it should be visible in your template.

Upvotes: 5

Related Questions