0

Condition: I have a model, created an empty table in the database, and I'm trying to create an html form that will fill in the fields of the corresponding columns of the table. And here's what my app looks like:

models.py

from django.db import models

class Cities(models.Model):
    city = models.CharField(max_length=100)

    def __str__(self):
    return self.state   

class Routes(models.Model):
    route_name = models.CharField(max_length=50, default='Route')
    lvl = models.IntegerField(default=0)
    about = models.TextField(max_length=1500)
    total_distance = models.IntegerField(default=0)
    city = models.ForeignKey(Cities, on_delete=models.CASCADE)

forms.py

from django.forms import ModelForm
from .models import Routes

class RouteForm(ModelForm):
    class Meta:
        model = Routes
        fields = '__all__'

views.py

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

from routes_form.forms import RouteForm


def getAbout(request):
    if request.method == 'POST':
        form = RouteForm(request.POST)
        if form.is_valid():
            form.save()
    return render(request, 'routes_form/form_page.html', {'form': form})

form.html

<form method="post">
        {% csrf_token %}
        <legend>
            <h2>About</h2>
        </legend>
        {{ form }}
        <input type="text" placeholder="Write more about the route: about waypoints, points of interest and warnings.">
        <input type="submit" value="Send route">
</form>

I have already tried to do everything as indicated in the Django Forms documentation. But still something is wrong. Even at the moment of starting the server, it writes an error:

cannot access local variable 'form' where it is not associated with a value
2
  • You have to pass the parameter 'context' in order to gain acccess to the variable 'form'. Try return render(request, 'routes_form/form_page.html', context={'form': form}). Commented Nov 27, 2022 at 0:40
  • Unfortunately, it did not work, but thanks to your answer, I found the problem. And now I will solve it. The point was that the form variable was local and was not visible when it was returned. Commented Nov 27, 2022 at 0:45

3 Answers 3

1

It is because you haven't defined form for GET method so:

def getAbout(request):
    if request.method == 'POST':
        form = RouteForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('some_view_name_to_redirect')
    else:
        form=RouteForm()
    return render(request, 'routes_form/form_page.html', {'form': form})

Note: Models in Django are written in singular form, as Django itself add s as the suffix, so it is better to name the models as City and Route.

Sign up to request clarification or add additional context in comments.

Comments

0

Here you passed form = RouteForm(request.POST) object for POST request you need to pass for GET request so, when def getAbout(request) function called with GET request then renders it like this ...

def getAbout(request):
  form=RouteForm() # <---- called at GET request
  if request.method == 'POST':
    form = RouteForm(request.POST) # <---- called at POST request
    if form.is_valid():
      form.save()
      return redirect("/")
  return render(request, 'routes_form/form_page.html', {'form': form})

Comments

0

You need to initialize the form before if condition in views.py

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

from routes_form.forms import RouteForm


def getAbout(request):
    form = RouteForm()
    if request.method == 'POST':
        form = RouteForm(request.POST)
        if form.is_valid():
            form.save()
    return render(request, 'routes_form/form_page.html', {'form': form})

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.