问题
Background
What I would like to do is to implement a form to insert datetime with the specific data type (like 2019-10-23 22:38:18) on a web application written in Python Flask and SQLAlchemy.
my former question: Inappropriate datetime datatype and error on Flask App
Problem and Error message
When I edit
@app.route('/')
def index():
return render_template('index.html', data=Todo.query.all(), form=form)
It returned the error "NameError: name 'form' is not defined"
But, when I get rid of form=form from my current code, the error has changed to "Bad Request The browser (or proxy) sent a request that this server could not understand." on the transited page after clicking the submit button.
Code
app.py
from flask import Flask, render_template, request, redirect, url_for, abort, jsonify
from flask_sqlalchemy import SQLAlchemy
import sys
import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://username@localhost:5432/datetime'
db = SQLAlchemy(app)
class Todo(db.Model):
__tablename__ = 'todos'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String) # Jon
city = db.Column(db.String(120)) # New York
datetime = db.Column(db.DateTime()) # 2019-10-23 22:38:18
def __repr__(self):
return f'<Todo {self.id} {self.name} {self.city} {self.datetime}>'
db.create_all()
@app.route('/todos/create', methods=['POST'])
def create_todo():
error = False
body = {}
try:
name = request.form['name']
city = request.form['city']
datetime = request.form['datetime']
todo = Todo(name=name, city=city)
db.session.add(todo)
db.session.commit()
body['name'] = todo.name
body['city'] = todo.city
body['datetime'] = todo.datetime
except:
error = True
db.session.rollback()
print(sys.exc_info())
finally:
db.session.close()
if error:
abort (400)
else:
return jsonify(body)
# Filters
def format_datetime(value, format='medium'):
date = dateutil.parser.parse(value)
if format == 'full':
format="EEEE MMMM, d, y 'at' h:mma"
elif format == 'medium':
format="EE MM, dd, y h:mma"
return babel.dates.format_datetime(date, format)
app.jinja_env.filters['datetime'] = format_datetime
@app.route('/')
def index():
return render_template('index.html', data=Todo.query.all(), form=form)
index.html
<html>
<head>
<title>Todo App</title>
<style>
.hidden{
display: none;
}
</style>
</head>
<body>
<form method="post" action="/todos/create">
<h4>name</h4>
<input type= "text" name="name" />
<h4>city</h4>
<input type= "text" name="city" />
<div>
<label for="datetime">Date Time</label>
<input id="datetime" type="datetime-local">
</div>
<input type= "submit" value="Create" />
</form>
<div id= "error" class="hidden">Something went wrong!</div>
<ul>
{% for d in data %}
<li>{{d.name}}</li>
<li>{{d.city}}</li>
<li>{{d.datetime}}</li>
{% endfor %}
</ul>
<script>
const nameInput = document.getElementById('name');
const cityInput = document.getElementById('city');
const dtInput = document.getElementById('datetime');
document.getElementById('form').onsubmit = function(e) {
e.preventDefault();
const name = nameInput.value;
const city = cityInput.value;
const datetime = dtInput.value;
descInput.value = '';
fetch('/todos/create', {
method: 'POST',
body: JSON.stringify({
'name': name,
'city': city,
'datetime': datetime,
}),
headers: {
'Content-Type': 'application/json',
}
})
.then(response => response.json())
.then(jsonResponse => {
console.log('response', jsonResponse);
li = document.createElement('li');
li.innerText = name;
li.innerText = city;
li.innerText = datetime;
document.getElementById('todos').appendChild(li);
document.getElementById('error').className = 'hidden';
})
.catch(function() {
document.getElementById('error').className = '';
})
}
</script>
</body>
</html>
Environment
Python 3.6.0
Flask 1.1.1
SQLAlchemy 1.3.10
PostgreSQL 11.5
回答1:
The error is raised since you do not create a form object anywhere before referencing it when passing it into your render_template function.
As for the bad request, it could be caused by you closing your db.session the first time that endpoint is called. So any following calls to the endpoint will try to access the closed session, throwing an error.
来源:https://stackoverflow.com/questions/58552236/error-when-aquiring-date-time-data-on-flask-app