Tourist Attractions Step 14 - Flask

Hi,

Could someone post a solution to Step 14 of the Tourist Attractions (Introduction to Flask) task? Some other, associated posts say that there may be an issue with the exercise; I was wondering whether this is still the case.

For the following code,

<form class="addform" action="{{ url_for('add_location') }}" method="POST">

I get the following error message.

jinja2.exceptions.UndefinedError: ‘add_location’ is undefined.

Which part of the other tasks could be leading to such a message?

Thank you.

Please refer to this guide when asking questions.

Also, we don’t give out solutions. We can help you understand your code and/or debug, or guide you to an answer (b/c it’s a learning forum).

Please:

  • include a link to the lesson
  • post your full formatted code, or a link to a GitHub repo of your code.

This is currently how my **locations.html ** looks:

<!-- extend from "base.html" here -->
{% extends "base.html" %}
<!-- begin block content here -->
{% block content %}
<h1>{{ categories[category] }}</h1>
<!-- insert category here -->

<div class="navbar">
  <!-- begin for loop here -->
  {% for category, label in categories.items() %}
  <a href="{{ category }}"> {{ label}}</a>
  <!-- set attribute and text here -->
  <!-- end for loop here -->
  {% endfor %}
</div>

<table>
  <colgroup>
    <col style="width: 20%" />
    <col style="width: 70%" />
    <col style="width: 10%" />
  </colgroup>
  <tbody class="loctable">
    {% for location in locations %}<!-- begin for loop here -->
    <tr>
      <td class="loc">{{ location.name }}</td>
      <!-- insert location name here -->
      <td class="desc">{{ location.description }}</td>
      <!-- insert location description here -->
      <td class="btns">
        <!-- start if statement here -->
        {% if location.category in ["recommended", "tovisit"] %}
        <form method="POST">
          <input type="submit" class="up" name="" value="&#8599;" />
          <!-- set name attribute here -->
          <input type="submit" class="del" name="" value="X" />
          <!-- set name attribute here -->
          <input
            type="submit"
            class="cl3"
            name="{{ location.name }}"
            value="Submit"
          />
        </form>
        <!-- end if statement here -->
        {% endif %}
      </td>
    </tr>
    <!-- end for loop here -->
    {% endfor %}
  </tbody>
</table>
<form class="addform" action="{{ url_for('add_location') }}" method="POST"> <!-- set action attribute here -->
    {{ add_location.hidden_tag() }}<!-- call hidden_tag() here -->

  <table>
    <colgroup>
      <col style="width: 40%" />
      <col style="width: 40%" />
      <col style="width: 20%" />
    </colgroup>
    <tbody>
      <tr>
        <td></td>
        <!-- insert location name label here -->
        <td></td>
        <!-- insert location description label here -->
        <td></td>
        <!-- insert location category label here -->
      </tr>
      <tr>
        <td></td>
        <!-- insert add_location name here -->
        <td></td>
        <!-- insert add_location description here -->
        <td>
          <!-- begin for loop here -->

          <div></div>
          <!-- insert button here -->
          <!-- end for loop here -->
        </td>
      </tr>
      <tr>
        <td></td>
        <!-- insert submit here -->
      </tr>
    </tbody>
  </table>
</form>
<!-- end block content here -->
{% endblock %}

This is how the other relevant doc looks (forms.py):

from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, TextAreaField, RadioField
from wtforms.validators import DataRequired

class FieldsRequiredForm(FlaskForm):
  """Require radio fields to have content. This works around the bug that WTForms radio fields don't honor the `DataRequired` or `InputRequired` validators."""
  class Meta:
    def render_field(self, field, render_kw):
      if request.method == "POST":
        render_kw.setdefault("required", True)
      return super().render_field(field, render_kw)

categories = [("recommended","Recommended"), ("tovisit", "Places To Go"), ("visited", "Visited!!!")]

## Create Form Here
class AddLocationForm(FieldsRequiredForm):
  name = StringField("Location Name", validators=[DataRequired()])
  description = TextAreaField("Location Description", validators=[DataRequired()])
  category = RadioField("Categories", choices=[categories])
  submit = SubmitField("Add Location")

Something that may have contributed to the code not working initially is that I put the Step 14 code into the wrong part of the HTML file. The current code (as it stands) has this error removed.

The link to the lesson is:

https://www.codecademy.com/paths/build-python-web-apps-flask/tracks/introduction-to-flask/modules/flask-templates-and-forms/projects/tourist-attractions-app

Hi there,

I got the same error and then combed through my entire code to find out where I had gone wrong.

Here’s where things went wrong for me - in the return statement for the locations route.

return render_template(“locations.html”, category=category, categories=categories, locations=locations, add_location=add_location)

Let me know if this helps:

from flask import Flask, render_template, request, redirect, url_for from locations import Locations from forms import AddLocationForm app = Flask(__name__) app.config['SECRET_KEY'] = 'SECRET_PROJECT' visit = Locations() categories = {"recommended": "Recommended", "tovisit": "Places To Go", "visited": "Visited!!!", } UP_ACTION = "\u2197" DEL_ACTION = "X" @app.route("/<category>", methods=["GET", "POST"]) def locations(category): add_location = AddLocationForm() locations = visit.get_list_by_category(category) ## Check the request for form data and process if request.method == "POST": [(name, action)] = [(request.form.items())] if action == UP_ACTION: visit.moveup(name) elif action == DEL_ACTION: visit.delete(name) ## Return the main template with variables return render_template("locations.html", category=category, categories=categories, locations=locations, add_location=add_location) @app.route("/add_location", methods=["POST"]) def add_location(): ## Validate and collect the form data if True: name=None description=None category=None visit.add(name, description, category) ## Redirect to locations route function return "" @app.route("/") def index(): ## Redirect to locations route function return ""