local variable referenced before assignment django error

Question:

This is my view.py and when i have a form which when i submit with the required fields it gives an appropriate output but when i don’t input anything in the form and click submit i get an error saying “local variable ‘researcher’ referenced before assignment”.

Also i want to know how do i keep my form data saved on the destination page

def about_experiment(request,ex_link_name):

    if request.method == 'POST':
        form = AboutHelp(request.POST)
        if form.is_valid():
            researcher = form.cleaned_data['researcher']
            study = form.cleaned_data['study']

    else:
        form = AboutHelp()
    return render(request, 'about_experiment.html', {'researcher': researcher, 'study': study})

my form on the source page is

<form action="{% url 'lazer.views.about_experiment' exp.link_name %}" method="POST" name="form"> 
  {% csrf_token %}
      <label>Researcher Name(s):<input type="text" name="researcher">
    <lable>Study Summary<textarea rows="10" cols="50" placeholder="here you go" maxlength="500" class="form-control" name="study"></textarea>
      <br>
      <input type = "submit" value="Submit" class="btn btn-primary" />
  </form>

My destination page where the form outputs are present

<h4> Name : {{ researcher }} </h4><br>
<h4> Summary : {{ study }} </h4>
Asked By: unknown

||

Answers:

researcher and study are not assignment if request method is not POST and form is not valid. You should define this variable before if statement:

def about_experiment(request,ex_link_name):
    researcher = ''
    study = ''
    if request.method == 'POST':
    ...  
Answered By: neverwalkaloner

in else part of views.py you mentioned researcher variable in render method that is producing this error.

so please add

researcher = None

before if statement

and also add

study = None

that will also create same error

forms.py

from django import forms
from .models import AboutHelp

    class AboutHelpForm(forms.ModelForm):
        class Meta:
            model = AboutHelp
            fields = '__all__'

views.py

def about_experiment(request,ex_link_name):
    researcher = None 
    study = None
    form = AboutHelpForm(request.POST or None)
    if request.method == 'POST':
        if form.is_valid():
            form.save()
    return render(request, 'about_experiment.html', {'researcher': researcher, 'study': study})
Answered By: Neeraj Kumar

The problem is that you always use need the variables researcher and study in your render() function regardless of whether the method was POST or not. However, you only define the variables if the method is POST and the form is valid. You forgot to define the variables in the cases when the method is not POST or if the form is not valid.

One solution (given in previous answers) is to define the variable as '' or None at the beginning of the code. Then, if the method is POST and the form is valid you assign new values to the variables. And if the method is not POST or if the form is not valid, you can still use the variables (which do exist but have nothing in them).

Another solution is to define the variables in all else statements – see below.

def about_experiment(request,ex_link_name):

    if request.method == 'POST':
        form = AboutHelp(request.POST)
        if form.is_valid():
            researcher = form.cleaned_data['researcher']
            study = form.cleaned_data['study']
        else:
            researcher = ''
            study = ''
    else:
        form = AboutHelp()
        researcher = ''
        study = ''
    return render(request, 'about_experiment.html', {'researcher': researcher, 'study': study})
Answered By: Jakub Holan