Error when aquiring date time data on Flask app

白昼怎懂夜的黑 提交于 2019-12-11 14:29:00

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!