New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using Turbo-Flask to dynamically update <select> options from a database? #22
Comments
Give your select field an id attribute, then you can send a new version of it with a different list of options as an update. |
OK, thanks, so the template would look like <!-- template/options.html -->
<select id="mySelect">
{% for option in data %}
<option value="{{ option.value }}">{{option.name}}</option>
{% endfor %} and the call to Turbo-Flask turbo.push(turbo.replace(render_template('options.html'), 'mySelect')) ? |
Yeah, I think that should do it. But you need to close your |
OK, I'm getting a lot closer, however I'm now seeing a context error ( I think this is because my turbo-flask call is in a blueprint: # extensions.py
# Initialise Turbo for websocket connectivity
from turbo_flask import Turbo
turbo = Turbo() # devices.py
import logging
import sys
import threading
import time
import uuid
from flask import Blueprint, render_template, current_app
from flask_login import login_required, current_user
from . import db
from .models import *
from .extensions import turbo
devices = Blueprint('devices', __name__)
@devices.app_context_processor
def get_devices():
urd = []
for d in RegisteredDevices.query.filter(RegisteredDevices.device_is_registered == False).all():
urd.append(d)
return urd
@devices.before_app_first_request
def before_first_request():
threading.Thread(target=device_updates, args=(current_app._get_current_object(),)).start()
def device_updates(app):
with app.app_context():
while True:
print("Publishing...")
time.sleep(5)
turbo.push(turbo.replace(render_template('session_devices.html'), 'unregistered_devices')) # __init__.py
import os
import socket
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from .extensions import turbo
# init SQLAlchemy so we can use it later in our models
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['SERVER_NAME'] = os.getenv("APP_SERVER_NAME")
app.config['SECRET_KEY'] = os.getenv("APP_SECRET_KEY")
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv("APP_DB_URI")
db.init_app(app)
turbo.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
from .models import User
@login_manager.user_loader
def load_user(user_id):
# since the user_id is just the primary key of our user table, use it in the query for the user
return User.query.get(int(user_id))
# blueprint for auth routes in our app
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
# blueprint for non-auth parts of app
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
# blueprint for session parts of app
from .devices import devices as devices_blueprint
app.register_blueprint(devices_blueprint)
return app When I visit any URI, I get the following error on the screen and in the logs: 127.0.0.1 - - [19/Jan/2022 07:20:54] "GET /devices HTTP/1.1" 500 -
Traceback (most recent call last):
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
return self.wsgi_app(environ, start_response)
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 2076, in wsgi_app
response = self.handle_exception(e)
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
response = self.full_dispatch_request()
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask_login/utils.py", line 272, in decorated_view
return func(*args, **kwargs)
File "/home/ff/device_test/devices.py", line 32, in index
return render_template(
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/templating.py", line 146, in render_template
ctx.app.update_template_context(context)
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 756, in update_template_context
context.update(func())
TypeError: cannot convert dictionary update sequence element #0 to a sequence
127.0.0.1 - - [19/Jan/2022 07:20:54] "GET /devices?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 -
127.0.0.1 - - [19/Jan/2022 07:20:54] "GET /devices?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 -
127.0.0.1 - - [19/Jan/2022 07:20:54] "GET /devices?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
127.0.0.1 - - [19/Jan/2022 07:20:54] "GET /devices?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 -
Exception in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python3.9/threading.py", line 973, in _bootstrap_inner
self.run()
File "/usr/lib/python3.9/threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "/home/ff/device_test/devices.py", line 70, in device_updates
turbo.push(turbo.replace(render_template('session_devices.html'), 'unregistered_devices'))
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/templating.py", line 146, in render_template
ctx.app.update_template_context(context)
File "/home/ff/.local/share/virtualenvs/device_test/lib/python3.9/site-packages/flask/app.py", line 756, in update_template_context
context.update(func())
TypeError: cannot convert dictionary update sequence element #0 to a sequence It works fine until I try to push the DB query results to the turbo front-end, do I need to re-marshall the device data into an different dict? |
Your template context function appears to be returning something that is not a dict. |
OK, thanks, I'll close this off for now and debug the template issue! :) |
Hi, thanks for this library, it's looking like it will solve an issue that I have, I just can't get my head around how right now!
I'm working on a platform where devices can register themselves with a central database using MQTT. Users then select a device for a time-limited session, and assign it to a location via a web interface.
I've got the devices registering perfectly fine with the backend database, and my plan was to use Turbo-Flask to either:
/register
MQTT channel wait for new devicesTurbo-flask would then update a form select dropdown in the UI so that the user can select that device.
I've got the LoadAVG code working fine, I'm just struggling slightly to understand how I update a single form element rather than reloading an entire template!
The text was updated successfully, but these errors were encountered: