在Flask应用中查询日期时间数据时出错 [英] Error when aquiring date time data on Flask app

查看:123
本文介绍了在Flask应用中查询日期时间数据时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想做的是在用Python Flask和SQLAlchemy编写的Web应用程序上实现一种插入具有特定数据类型(例如2019-10-23 22:38:18)的日期时间的表单.

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.

我以前的问题:日期不当的数据类型和错误在Flask应用上

编辑时

@app.route('/')
def index():
    return render_template('index.html', data=Todo.query.all(), form=form)

返回错误"NameError:未定义名称'form'"

It returned the error "NameError: name 'form' is not defined"

但是,当我从当前代码中删除form = form时,错误已更改为"Bad Request浏览器(或代理)发送了该服务器无法理解的请求".点击提交按钮后,在过渡页面上显示.

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.

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

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>

环境

Python 3.6.0

Environment

Python 3.6.0

烧瓶1.1.1

SQLAlchemy 1.3.10

SQLAlchemy 1.3.10

PostgreSQL 11.5

PostgreSQL 11.5

推荐答案

由于将form对象传递给render_template函数之前在引用它之前没有在任何地方创建该对象,因此会引发错误.

The error is raised since you do not create a form object anywhere before referencing it when passing it into your render_template function.

对于错误的请求,可能是由于您在第一次调用端点时关闭db.session引起的.因此,随后对端点的任何调用都将尝试访问已关闭的会话,从而引发错误.

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.

这篇关于在Flask应用中查询日期时间数据时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆