#๐Ÿ”’ I want to use fields of my database as options in my <select>

110 messages ยท Page 1 of 1 (latest)

jade cypressBOT
#

@obsidian wedge

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

obsidian wedge
#

Python File

@app.route('/admin/games', methods=('GET', 'POST'))
def admingames():
    db = get_db()
    cursor = db.cursor()
    res = cursor.execute('SELECT team_id, teamname FROM teams')
    all_teams = [{'team_id':team_id, 'teamname':teamname} for team_id, teamname in res]
return render_template('games.html', all_teams=all_teams)```
#
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Games Admin Form</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='games.css') }}">
</head>
<body>
    <div class="title">
        <p>Games Admin Page</p>
    </div>
    <div class="flash-messages">
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                <ul class=flashes>
                    {% for message in messages %}
                    <li>{{ message }}</li>
                    {% endfor %}
                </ul>
            {% endif %}
        {% endwith %}
        {% block body %}{% endblock %}
    </div>
    <div class="headerphoto">
        <div>
            <form action="" method="post">

            <p>
                <label for ="date_time">Date played:</label>
                <input type="date" id="date_time" name="date_time" />


                
            </p>
            <p class="button">
                <button type="submit">Submit data</button>
            </p>

        </form> 
        </div>
</body>
</html>
#

I want my <select> to go where the gaps are in the HTML

lavish raft
#

Can't you do something similar to the flash-messages div above?

obsidian wedge
lavish raft
#

Write the equivalent Python, with some simplistic print() calls for the HTML. Then translate the various for-loops etc to the same template syntax as the with messages stuff above.

Is that a jinja template, or just something which looks like one?

obsidian wedge
lavish raft
obsidian wedge
lavish raft
#

I'm assuming you want to render the team data in the HTML? Seems like a normal enough thing to do.

#

Your team data is a list of dicts. Should be easy.

obsidian wedge
lavish raft
#

Ah.

obsidian wedge
lavish raft
#

So you need to fill in a <input> field.

obsidian wedge
#

Is it not <select>?

lavish raft
obsidian wedge
#

Or am I thinking of the wrong thing

lavish raft
obsidian wedge
#

Hold on let me check

lavish raft
#

I rarely write HTML.

#

You make your team_data like this:

all_teams = [{'team_id':team_id, 'teamname':teamname} for team_id, teamname in res]

obsidian wedge
#

I want one of these little drop down boxes

lavish raft
#

Got the HTML for that Volvo dropdown?

obsidian wedge
#
<form action="/action_page.php">
  <label for="cars">Choose a car:</label>
  <select name="cars" id="cars">
    <optgroup label="Swedish Cars">
      <option value="volvo">Volvo</option>
      <option value="saab">Saab</option>
    </optgroup>
    <optgroup label="German Cars">
      <option value="mercedes">Mercedes</option>
      <option value="audi">Audi</option>
    </optgroup>
  </select>
  <br><br>
  <input type="submit" value="Submit">
</form>
lavish raft
#

view-source on that page might just give it to you.

obsidian wedge
#

Not using any parameters though

lavish raft
#

Ok, so you've got a list of dicts in team_data.
So write this pure Python:

print('<select name="teams">')
for team in team_data:
    print(f'<option value="{team["team_id"]}">{team["teamname"]}</option>')
print('</select>')
#

So you access a dict a lot like a list, with [] and a key for the field you want.

obsidian wedge
#

so its a bit like 2d arrays

#

just with the names of the element

#

or the keys or whatever they are

lavish raft
obsidian wedge
#

so like

lavish raft
obsidian wedge
#
{% for team in team_data %}
        
{% endfor %}
lavish raft
#

You should probably say for team - it's a list, and each item is the whole team dict.

#

See the very first example on the page URL I cite above. It literally does what you want for a select, but for a ist.

obsidian wedge
#

may i ask what this does for team_id, teamname in res

lavish raft
#

(HTML list.)

#

I thought you wrote that code.

obsidian wedge
#

i got some help in #databases yesterday

#

just scroll up a tiny bit

lavish raft
#

Ok, so you're doing a SELECT, yes?

obsidian wedge
#

yeah the drop down menus

lavish raft
#

This SQL:

SELECT team_id, teamname FROM teams

selects every row ffrom the teams table and returns 2 columns from each row: team_id and teamname.

lavish raft
obsidian wedge
#

yeah i got that bit, its just the bit outside that

obsidian wedge
lavish raft
#

This runs the SQL and returns the result, which is a list of 2-tuples, with the 2-tuples having a value for each column.

obsidian wedge
#

yeah

lavish raft
#

So for item in res: is a for-loop which iterates over the list, and item would be a 2-tuple containing a team id and a team name in it.

obsidian wedge
#

ohhh for item in result

#

so it goes through every 2-tuple

lavish raft
#

Python has an unpacking assignment syntax. Eg:

x, y = 1, 2

which sets x=1 and y=2

#

The for team_id, teamname in res isan unpacking assignment - it unpacks each item into those to names.

obsidian wedge
#

okay i get it now

lavish raft
#

This:

all_teams = [{'team_id':team_id, 'teamname':teamname} for team_id, teamname in res]

is a list comprehension.

obsidian wedge
#

Okay thanks

lavish raft
obsidian wedge
#

i don't really know how

#
<select id="team_data">
    {% for teamname in team_data %}
        <option value = "teamname">
    {% endfor %}
    </ul>
#

thats as far as i got

lavish raft
#

Try "{{teamname}}" and see what HTML you get.

obsidian wedge
#

where do i put that?

lavish raft
#

<option value = "{{teamname}}">

obsidian wedge
#

ahh okay

lavish raft
#

But teamname will be a dict. You probably want {% for team in team_data %} and then to use {{team.team_id}} and {{team.teamname}} in the template inside the loop.

#

See the <li> line in the example on the page?

obsidian wedge
lavish raft
#

Right. So you have the drop down but the labels on the drop down are empty.

obsidian wedge
#

yeah

lavish raft
#

The label comes after the <option> tag, like:

<option value="3">Third</option>
obsidian wedge
#

ahh

lavish raft
#

So you need to fill in both those things.

#

So the value will be the team id, and the label is the team name.

#

That makes a form drop down which shows team names, but returns team ids when the form gets submitted.

obsidian wedge
#

still not appearing

#

Actually

#

Yes it is, after restarting the flask app

#

I need a way for it to be the ID

lavish raft
#

Right. So put the team_id in the value. use the teamname for the label.

obsidian wedge
#

Boom I did it

#

Now,

#

I need a way so that once that team has been selected

#

And data has been submitted

#

It takes the team_id from that team, and stores it in another database as the foreign key

lavish raft
#

Well you need a flask endpoint to receive the form data.

obsidian wedge
#

Let me show you what I have

lavish raft
#

Then probably an SQL INSERT statement to insert the data into the relevant table.

obsidian wedge
#
    if request.method == 'POST':
        teamname = request.form['teamname']
        error = None

        if not teamname:
            error = 'Team name is required.'
        if error is not None:
            flash(error)
        else:
            db = get_db()
            db.execute('INSERT INTO teams (teamname) VALUES (?)', (teamname,))
            db.commit()
            return redirect(url_for('index'))
#

so thats copy and pasted from another page of mine

#

i just need to modify it to fit my current page

lavish raft
#

Yeah. The team field won't be a team name, it will be an id.

#

But yes, that's the right shape.

obsidian wedge
#

yeah let me sort it out quickly

#

and if its wrong we can make changes

lavish raft
#

I need to go soon.

obsidian wedge
#

okay thats fine youve helped me alot

lavish raft
#

You'll need to debug it yourself. Remember, lots of print() calls to show the values you get from the form and so forth.

#

Good lock.

twin moss
obsidian wedge
jade cypressBOT
#
Python help channel closed using Discord native close action

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.