Как принять дату ISO в качестве параметра маршрута Flask - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть этот сырой sql код, и мне нужно переписать его как запрос SQlalchemy в Flask:

@app.route('/view/<date>')
def view(date):
    db = get_db()
    cur = execute('select entry_date from log_date where entry_date = ?', [date])
    result = cur.fetchone()

    d = datetime.strptime(str(result['entry_date']),'%Y%m%d')
    pretty_date = datetime.strftime(d, '%B %d, &Y)

    return render_template('day.htm;',date=pretty_date)

здесь я пытался сделать:

@app.route('/view/<entry_date>',methods=['GET','POST'])
def view(entry_date):
    dates = Log_date.query.filter_by(entry_date=entry_date).first()
    selected_date = datetime.strptime(dates, "%Y%m%d").date()

    """foods = Food.query.with_entities(Food.id,Food.name).all()"""
    return render_template('day.html',selected_date=selected_date)

Но страница по-прежнему не найдена.

Обратите внимание, что entry_date - это DateTime в моих моделях:

class Log_date(db.Model):
id = db.Column(db.Integer, primary_key=True)
entry_date = db.Column(db.DateTime,nullable=False)

Дополнительно я попытался преобразовать его с помощью конвертера DateTime следующим образом:

from datetime import datetime
from werkzeug.routing import BaseConverter, ValidationError


class DateConverter(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:
            return datetime.strptime(value, '%Y-%m-%d').date()
        except ValueError:
            raise ValidationError()

    def to_url(self, value):
        return value.strftime('%Y-%m-%d')


app.url_map.converters['date'] = DateConverter

но по-прежнему нет результата.

1 Ответ

0 голосов
/ 28 апреля 2020

Ниже приведен простой пример отдельного файла. Проверьте результаты браузера для следующих запросов:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...