1

I'm building a Netflix like website for my Devops course. I made a Python list of dictionaries (Mockfilms) to define my films, and want to populate a database (Ratings) with reviews in preparation for sending data in the format :filmid: :userid: :rating: to a recommendation engine.

My index page is a list of film images with a link to a review form under each one. I want each review form to appear on a different url (/review/ID where ID is saved in mockfilms as oid). In order to do this I want to access mockfilms.oid, then pass it to the view function to make the url for the form. Once the form is complete I then want to add this ID to the Ratings database. Here is what I have so far:

Index:

{% extends "base.html" %}

{% block content %}
    <h1>Hello, {{ current_user.username }}! Welcome to our extensive video library:</h1>
    {% for film in mockfilms %}
    {% set ID = film.oid %}
    <div>
        <a href = {{ film.video }}>
            <img src = {{ film.image }} alt = "doh" style = "width:200px;height:200px;border:0;">
        </a>
    </div>
    <div>

        <a href={{ url_for('review', ID) }}"> ">Leave a review here!</a>
    {% endfor %}
{% endblock %}

Route:

@app.route('/review/<ID>', methods = ['GET', 'POST'])
@login_required
def review(ID):
    form = ReviewForm()
    if form.validate_on_submit():
        review = Ratings(User_id = current_user.id, Score_given = form.score.data, Film_id = ID)
        db.session.add(review)
        db.session.commit()
        flash('Thanks for your review')
        return redirect(url_for('index'))
    return render_template('review.html', title='Review Page', form=form)

The following error is what I get when I run it:

File "/home/jc/Desktop/Lokal/DevopsAssig/microblog/Kilfinnan/lib/python3.5/site-packages/werkzeug/routing.py", line 1768, in build raise BuildError(endpoint, values, method, self) werkzeug.routing.BuildError: Could not build url for endpoint 'review'. Did you forget to specify values ['ID']?

From this I assume that the issue is with the ID variable within this template. My searchings and learnings led me to believe that {% set %} in the index template would let me declare the ID variable and then use it in the dynamic.

James Cooper
  • 57
  • 3
  • 11
  • Problem Resolved - functional syntax provided by @abigperson. It turns out I had another call to urlfor review elsewhere in my templates and it was this that caused the error. – James Cooper Jan 16 '18 at 08:44

2 Answers2

1

Try this:

{% block content %}
    <h1>
        Hello, {{ current_user.username }}! 
        Welcome to our extensive video library:
    </h1>
    {% for film in mockfilms %}
    <div>
        <a href="{{ film.video }}">
            <img src="{{ film.image }}" alt="doh" style="width:200px;height:200px;border:0;" />
        </a>
    </div>
    <div>
        <a href="{{ url_for('review', ID=film.oid) }}">
            Leave a review here!
        </a>
    </div>
    {% endfor %}
{% endblock %}

Ultimately your solution was quite close, but it is not necessary to use the Jinja set command when you need to pass the variable into url_for() function using the keyword for the parameter. You could still do it using {% set ID = film.oid %} but it would be a bit superfluous.

abigperson
  • 5,252
  • 3
  • 22
  • 25
  • Thanks for the response! I've tried this exactly as is but the same error is returned. – James Cooper Jan 15 '18 at 16:50
  • Have a look here: https://stackoverflow.com/questions/7478366/create-dynamic-urls-in-flask-with-url-for. The other answerer and I both picked up on the same issue... I don't see anything else wrong and can't test/replicate the issue. Sorry this did not help. – abigperson Jan 15 '18 at 16:53
  • Fixed! I'd forgotten that several days ago (back when i was deciding on how I'd structure the site) I'd left a call to Url_for(review) in my base.html file, and it seems that it was that call rather than this one that caused the issue. Thanks so much for giving me the assurance that the problem lay elsewhere - this was a massive help. – James Cooper Jan 16 '18 at 08:41
0

Try to provide key=value arguments into your url_for function.

Something like this

<a href={{ url_for('review', ID=ID) }}"> ">Leave a review here!</a>

Also Flask have a great documentation, Flask docs