Sorry I couldn't come up with a clear title, I'm not exactly sure what it is called that I want to accomplish. Also english is not my first language so please bear with me.
I've set up a database with two tables "Sensors" and "SensorValues". There should be a one-to-many relationship so that one sensor can have many readings but the readings can belong to only one sensor.
I'm using Flask and flask-sqlalchemy.
Database models:
class Sensor(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, nullable=False,)
gpiopin = db.Column(db.INT, unique=False, nullable=False,)
stype = db.Column(db.String(20), unique=False, nullable=False,)
values = db.relationship('SensorValues', backref='author', lazy=True) #not a column in table, just backreference
def __repr__(self):
return f"Sensor('{self.name}', '{self.gpiopin}', '{self.stype}')"
class SensorValues(db.Model):
id = db.Column(db.Integer, primary_key=True)
reading = db.Column(db.String(64), unique=False)
timestamp = db.Column(db.DateTime, unique=False, nullable=False, default=datetime.utcnow)
sensor_id = db.Column(db.Integer, db.ForeignKey('sensor.id'), nullable=False)
def __repr__(self):
return f"Value('{self.reading}', '{self.timestamp}')"
Here's the flask route for home.html:
@app.route("/", methods=['POST', 'GET'])
def home():
sensors = Sensor.query.all()
posts = SensorValues.query.all()
return render_template('home.html', posts=posts, sensors=sensors, db=db)
How I generate the table in home.html
<tbody>
{% for sensor in sensors %}
<tr>
<td>{{ sensor.name }}</td>
<td>{{ sensor.gpiopin }}</td>
<td>{{ sensor.stype }}</td>
<td>{{ sensor.values.reading }}</td> <- Where I want the latest reading of the specific sensor in the SensorValues to appear
</tr>
{% endfor %}
</tbody>
Now, I have another table which lists all the readings and the names of the sensors they belong to. It's basically a history and this way it works because I'm looping the SensorValues table directly.
{% for post in posts %}
<tr>
<td>{{ post.author.name }}</td>
<td>{{ post.author.stype }}</td>
<td>{{ post.reading }}</td>
<td>{{ post.timestamp }}</td>
</tr>
{% endfor %}
I tried to change the first loop to this:
{% for sensor in sensors %}
<tr>
<td>{{ sensor.name }}</td>
<td>{{ sensor.gpiopin }}</td>
<td>{{ sensor.stype }}</td>
{{ lastvalue = SensorValues.filter_by(sensor_id=sensor.id).last()}}
<td>{{ lastvalue.reading }}</td>
</tr>
{% endfor %}
Where I tried to make a filter query to the SensorValues table with the current sensor.id (the id of the Sensor the for loop is currently in) and logically I think that could work but the syntax is not correct. I got the Jinja error:
expected token 'end of print statement', got '='
Can I even do the query in the home.html or do I have to do it in the routes before the page is rendered?