12

I'm trying to make a form get information from the user and use this information to send a email. Here's my code:

#forms.py
from django import forms

class ContactForm(forms.Form):
    nome = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    msg = forms.CharField(
        required=True,
        widget=forms.Textarea
    )

#views.py
from django.shortcuts import render, redirect, get_object_or_404, HttpResponseRedirect, render_to_response
from django.core.mail import send_mail
from .forms import ContactForm

def contato(request):
    form_class = ContactForm
    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid():
            nome = request.POST.get('nome')
            email = request.POST.get('email')
            msg = request.POST.get('msg')

            send_mail('Subject here', msg, email, ['[email protected]'], fail_silently=False)
            return HttpResponseRedirect('blog/inicio')
    return render(request, 'blog/inicio.html', {'form': form})


#contato.html
{% extends "blog/base.html" %}
{% block content %}

                    <form role="form" action="" method="post">
                        {% csrf_token %}
                        {{ form.as_p }}
                        <button type="submit">Submit</button>
                    </form>
{% endblock %}

and when I try to enter in contact page I get this error:

local variable 'form' referenced before assignment

enter image description here

It is saying tha the error is in this line of views.py:

return render(request, 'blog/inicio.html', {'form': form})

I'm a little new on Django, can you please help me?

4 Answers 4

16

You define the form variable in this if request.method == 'POST': block. If you access the view with a GET request form gets not defined. You should change the view to something like this:

def contato(request):
    form_class = ContactForm
    # if request is not post, initialize an empty form
    form = form_class(request.POST or None)
    if request.method == 'POST':

        if form.is_valid():
            nome = request.POST.get('nome')
            email = request.POST.get('email')
            msg = request.POST.get('msg')

            send_mail('Subject here', msg, email, ['[email protected]'], fail_silently=False)
            return HttpResponseRedirect('blog/inicio')
    return render(request, 'blog/inicio.html', {'form': form})
Sign up to request clarification or add additional context in comments.

Comments

3

The Django docs handle this, but slightly differently from the other answers. See https://docs.djangoproject.com/en/dev/topics/forms/#using-a-form-in-a-view

Using an else, if the request is not POST then create the blank form. The below is pasted directly from the docs.

def get_name(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

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

Comments

0

If there can be so to say - collateral damage by initializing an empty form , then you may also provide a dummy value as a filler , till the request.POST is initialized ...

def contato(request):
    form = "Dummy String"
    form_class = ContactForm

    # if request is not post, initialize an empty form
    #form = form_class(request.POST or None) # Maybe Not 

    form = form_class(request.POST) # Instead 
    if request.method == 'POST':
        if form.is_valid():
            nome = request.POST.get('nome')
            email = request.POST.get('email')
            msg = request.POST.get('msg')

            send_mail('Subject here', msg, email, ['[email protected]'], fail_silently=False)
            return HttpResponseRedirect('blog/inicio')
    return render(request, 'blog/inicio.html', {'form': form})

Comments

0

The only issue you have is you did not declare ContactForm as function, change FROM this;

def contato(request):
    form_class = ContactForm
    if request.method == 'POST':

TO;

def contato(request):
    form_class = ContactForm()
    if request.method == 'POST':

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.