Ниже приведен простой пример отдельного файла. Проверьте результаты браузера для следующих запросов:
URL-адрес не найден, 404 ответ
http://127.0.0.1:5000/view
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Действительная дата ISO, но не в базе данных
http://127.0.0.1:5000/view/2019-12-31
Date:2019-12-31 not found
Действительная дата ISO и в базе данных
http://127.0.0.1:5000/view/2020-01-01
Date:2020-01-01 found
Недопустимая дата ISO, без месяца 13, ответ 404
http://127.0.0.1:5000/view/2020-13-01
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Вот код, примечание использует flask -sqlalchemy, а тип entry_date
является Sqlalchemy Date()
.
from flask import Flask, url_for
from datetime import datetime, date
from werkzeug.routing import BaseConverter, ValidationError
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class LogDate(db.Model):
id = db.Column(db.Integer, primary_key=True)
entry_date = db.Column(db.Date(), nullable=False)
def __str__(self):
return f'ID: {self.id}; Entry Date: {self.entry_date}'
class ISODateConverter(BaseConverter):
"""Extracts a ISO8601 date from the path and validates it."""
regex = r'\d{4}-\d{2}-\d{2}'
def to_python(self, value):
try:
# try and convert a string to a datetime object and then get a date object
return datetime.strptime(value, '%Y-%m-%d').date()
except ValueError:
raise ValidationError()
def to_url(self, value):
if isinstance(value, date):
return value.strftime('%Y-%m-%d')
app = Flask(__name__)
app.url_map.converters['iso_date'] = ISODateConverter
app.config['SECRET_KEY'] = '123456790'
# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db.init_app(app)
@app.route('/view/<iso_date:input_date>')
def view(input_date):
print(type(input_date))
# first() returns a single object or None
_log_date = LogDate.query.filter(LogDate.entry_date == input_date).first()
# or using filter_by
# _log_date = LogDate.query.filter_by(entry_date=input_date).first()
if not _log_date:
return f'Date:{input_date} not found'
return f'Date:{input_date} found !!!'
@app.route('/routes')
def routes():
_logs = LogDate.query.all()
# Internal routes
_html = ['<h1>Internal Routes</h1']
for _log in _logs:
_url = url_for('view', input_date=_log.entry_date)
_html.append(f'<p>{str(_log)} <a href="{_url}">{_url}</a></p>')
# External routes for use in Email etc
_html.append('<h1>External Routes</h1')
for _log in _logs:
_url = url_for('view', input_date=_log.entry_date, _external=True)
_html.append(f'<p>{str(_log)} <a href="{_url}">{_url}</a></p>')
return '\n'.join(_html)
@app.before_first_request
def build_sample_db():
db.drop_all()
db.create_all()
# add three dates
db.session.add_all([LogDate(entry_date=d) for d in [date(2020, 1, 1), date(2020, 2, 1), date(2020, 3, 1)]])
db.session.commit()
if __name__ == '__main__':
app.run()