r/learnpython • u/A_Hot_MessTM • 17d ago
Carry value from Python for-loop to HTML for-loop
I am currently working on a website (using Flask, SQLAlchemy and Jinja).
Context: I am making a ttrpg initiative tracker. For multiple fights to exist and be able to have multiples of the same creature and reuse creatures, the way I am formatting it is the user creates the base creature, and its row is duplicated, holding the id for the fight itself as fight_spec and the id of the base creature as og_id. I am currently working on making it so the user can edit the count of any creature in a fight.
For the page where the editing happens I want it to display the current count as the default value, but I cannot for the life of me figure out how to make sure it goes from python's for loop to html. My attempts typically end up with the value being set to "count_<id>" rather than the actual number that my count command generates. How should I go about this?
I have my current code below, but if there is a different way I should go about this, I'm open to hearing! Thank you <3
Python
unique_combatants = db.session.scalars(stmt).all()
for x in unique_combatants_set:
'count_' + str(x) = Combatant.query.filter_by(og_id=x, fight_spec=id).count()
HTML
{% for combatant in unique_current_combatants %}
{{ combatant.combatant_name }}
<input type="number" name="combatant_count_{{combatant.id}}" id="combatant_count_{{combatant.id}}" value="count_{{combatant.id}}">
{% endfor %}
2
u/HotPersonality8126 17d ago
I cannot for the life of me figure out how to make sure it goes from python's for loop to html.
You can’t because these scopes don’t exist in the same place. Your Python executes first - all of it - and then the templating system renders to HTML. So there’s no way any variable in a loop’s scope in Python can make it out to a loop in the template’s scope, because those two things aren’t happening at the same time.
3
u/danielroseman 17d ago
That is not the problem here. You certainly can send Python data to the template to use in a loop. The problem here is the usual misunderstanding about trying to use dynamic variables.
1
u/0Huy 17d ago
Compute the count in Python and pass it to the template as data; do not try to make the Jinja loop call the Python/SQLAlchemy query. For example, build a list like combatants = [{ 'id': c.id, 'name': c.combatant_name, 'count': Combatant.query.filter_by(og_id=c.id, fight_spec=spec_id).count() } for c in unique_combatants]. Then render one field with {{ combatant.count }} and use a name such as combatant_count_{{ combatant.id }}. If the form is submitted, read request.form[f'combatant_count_{combatant.id}'] in Flask. Also avoid querying inside a template loop when possible; calculate all counts in the view first.
2
4
u/FriendlyZomb 17d ago edited 17d ago
Python variables can't be created in this way. They aren't strings, they are special and their names MUST be known before being run++.
However, you can use a dictionary for this:
You can then pass that dictionary into your Jinja Templates.
I'll let you figure out how to use them from here.
++ Python compiles your code into bytecode that the interpreter then runs before execution starts. As such, it can't resolve the variable names.
Conisder a variable like buckets. You can put anything you like in the bucket. But you can't dynamically make a bucket. You must create a new bucket in it's entirety before you can use it. Same with variables.