Update: Set the attributes of an existing object in the database.
SQL 语句
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
SQLAlchemy ORM
user = User.query.get(some_id)
user.name = 'Some new name'
db.session.commit()
The if statement in Jinja.
{
% if users %}
<ul>
{
% for user in users %}
<li>
{
{
user.username|e }}
</li>
{
% endfor %}
</ul>
{
% endif %}
{
% if users %}
Kenny is sick
{
% elif kenny.health %}
Kenny is health
{
% else %}
Keeny looks okay
{
% endif %}
<!DOCTYPE html>
<html>
<head>
<title>Todo app</title>
<style>
.hidden {
display:none;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<form id="form">
<input type="text" id="description" name="description" />
<input type="submit" value="Create" />
</form>
<div id="error" class="hidden">Something went wrong!</div>
<ul id="todos">
{% for d in data %}
<li>
<input class="check-completed" data-id="{
{ d.id }}" type="checkbox" {% if d.completed %} checked {% endif %} />
{
{ d.description }}
</li>
{% endfor %}
</ul>
<script>
// Loop over all of these checkbox elements and listen to the change event with a on change function.
const checkboxes = document.querySelectorAll('.check-completed');
for (let i = 0; i < checkboxes.length; i++) {
const checkbox = checkboxes[i];
checkbox.onchange = function(e) {
console.log('event', e);
const newCompleted = e.target.checked;
const todoId = e.target.dataset['id'];
fetch('/todos/' + todoId + '/set-completed', {
method: 'POST',
body: JSON.stringify({
'completed': newCompleted
}),
headers: {
'Content-Type': 'application/json'
}
})
.then(function() {
document.getElementById('error').className = 'hidden';
})
.catch(function() {
document.getElementById('error').className = '';
})
}
}
// Select on the form
// onsubmit handler to default wound up sending information to the server
// Using the event object, e
document.getElementById('form').onsubmit = function(e) {
// The default behaviro would have done that full page refresh and
// submitted it using the method and action attributes up
e.preventDefault();
// Send the post requests asynchronously using fetch
fetch('/todos/create', {
method: 'POST',
body: JSON.stringify({
// The value of whatever the user has typed into the description field.
'description': document.getElementById('description').value
}),
headers: {
'Content-Type': 'application/json'
}
})
// give back a promise by which we can then use the
// then method
// callback should give us back a response
.then(function(response) {
// parse out the response which will initially be a string as a JSON response
return response.json();
})
// manipulate the JSON response
.then(function(jsonResponse) {
console.log(jsonResponse);
// Append a child Li element here
const liItem = document.createElement('LI');
liItem.innerHTML = jsonResponse['description'];
document.getElementById('todos').appendChild(liItem);
// it did succeed
document.getElementById("error").className = 'hidden';
})
// catch handler
.catch(function() {
// Remove the class name
document.getElementById("error").className = '';
})
}
</script>
</body>
</html>
from flask import Flask, render_template, request, redirect, url_for, jsonify
from flask_sqlalchemy import SQLAlchemy
import sys
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://username@localhost:5432/todoapp'
db = SQLAlchemy(app)
# Link to Flask app as well as the SQLAlchemy database
# migrate will do is start it up so that we can start using the Flask databae migrate commands to began initializing migrations
# and upgrading and downgrading and generating migrations as well.
migrate = Migrate(app, db)
class Todo(db.Model):
__tablename__ = 'todos'
id = db.Column(db.Integer, primary_key=True)
description = db.Column(db.String(), nullable=False)
completed = db.Column(db.Boolean, nullable=False, default=False)
def __repr__(self):
return f'<Todo {
self.id} {
self.description}>'
# Ensure the tables are created for all the models that we've created and they haven't been created.
# db.create_all()
@app.route('/todos/create', methods=['POST'])
def create_todo():
error = False
body = {
}
try:
# get_json is that it fetches the JSON body that was sent to an object key description.
description = request.get_json()['description']
todo = Todo(description=description)
db.session.add(todo)
db.session.commit()
body['description'] = todo.description
except:
error = True
db.session.rollback()
# debugging sentence
print(sys.exc_info())
finally:
db.session.close()
if not error:
# return a useful JSON object that includes that description.
# jsonify will return JSON data to the client for us.
# whatever we pass in as our JSON object.
return jsonify(body)
@app.route('/todos/<todo_id>/set-completed', methods=['POST'])
def set_completed_todo(todo_id):
try:
completed = request.get_json()['completed']
print('completed', completed)
todo = Todo.query.get(todo_id)
todo.completed = completed
db.session.commit()
except:
db.session.rollback()
finally:
db.session.close()
return redirect(url_for('index'))
@app.route('/')
def index():
return render_template('index.html', data=Todo.query.order_by('id').all())
运行命令:
$ FLASK_APP=app.py FLASK_DEBUG=true flask run
在网页中,点击check了之后,刷新页面,数据还在网页上,因为数据已经存储在数据库里