TypeError: парсер должен быть строкой или символьным потоком, а не datetime - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь сделать так, чтобы веб-страница показывала все предстоящие шоу, перечисленные в базе данных, вместе с кучей информации о каждом шоу, которая хранится в таблицах мест проведения и артистов соответственно. Я запрашиваю таблицу Show, а затем для каждой строки в этом результате связываю таблицы Artist и Venue. Поскольку ошибка имеет какое-то отношение к datetime, я предполагаю, что ошибка связана либо с if show.start_time > current_time:, либо с "start_time": show.start_time, но ошибка не указывает, где она находится. Я попытался преобразовать как current_time, так и show.start_time в строку, чтобы посмотреть, работает ли это, но не повезло. Что я делаю не так?

@app.route('/shows')
def shows():

  current_time = datetime.now()

  data = []

  allshows = Show.query.all()

  for show in allshows:
    artist = Artist.query.get(show.artist_id)
    venue = Venue.query.get(show.venue_id)

    if show.start_time > current_time:
      data.append({
        "venue_id": show.venue_id,
        "venue_name": venue.name,
        "artist_id": show.artist_id,
        "artist_name": artist.name,
        "artist_image_link": artist.image_link,
        "start_time": show.start_time
      })
 
  return render_template('pages/shows.html', shows=data)

Если это поможет, вот модели, связанные с ним:

class Venue(db.Model):
    __tablename__ = 'venues'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    city = db.Column(db.String(120))
    state = db.Column(db.String(120))
    address = db.Column(db.String(120))
    phone = db.Column(db.String(120))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    genres = db.Column(db.ARRAY(db.String))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    website = db.Column(db.String(300))
    seeking_talent = db.Column(db.Boolean)
    seeking_description = db.Column(db.String(120))
    shows = db.relationship('Show', backref='venue', lazy=True)

class Artist(db.Model):
    __tablename__ = 'artists'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    city = db.Column(db.String(120))
    state = db.Column(db.String(120))
    phone = db.Column(db.String(120))
    genres = db.Column(db.String(120))
    image_link = db.Column(db.String(500))
    facebook_link = db.Column(db.String(120))
    website = db.Column(db.String(300))
    seeking_shows = db.Column(db.Boolean)
    seeking_description = db.Column(db.String(120))
    shows = db.relationship('Show', backref='artist', lazy=True)        

class Show(db.Model):
    __tablename__ = 'shows'

    id = db.Column(db.Integer, primary_key=True)
    artist_id = db.Column(db.Integer, db.ForeignKey('artists.id'), nullable = False)
    venue_id = db.Column(db.Integer, db.ForeignKey('venues.id'), nullable = False)
    start_time = db.Column(db.DateTime, nullable = False)

    def __repr__(self):
        return '<Show {} {}>'.format(self.artist_id, self.venue_id)

Изменить: включая полную трассировку.

Traceback (most recent call last):
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/app.py", line 547, in shows
    return render_template('pages/shows.html', shows=data)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/templating.py", line 137, in render_template
    return _render(
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/flask/templating.py", line 120, in _render
    rv = template.render(context)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/templates/pages/shows.html", line 1, in top-level template code
    {% extends 'layouts/main.html' %}
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/templates/layouts/main.html", line 103, in top-level template code
    {% block content %}{% endblock %}
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/templates/pages/shows.html", line 9, in block "content"
    <h4>{{ show.start_time|datetime('full') }}</h4>
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/app.py", line 101, in format_datetime
    date = dateutil.parser.parse(value)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 1168, in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 556, in parse
    res, skipped_tokens = self._parse(timestr, **kwargs)
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 675, in _parse
    l = _timelex.split(timestr)         # Splits the timestr into tokens
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 192, in split
    return list(cls(s))
  File "/Users/ZEMEL/Dropbox (Personal)/Code/fyyurr/env/lib/python3.8/site-packages/dateutil/parser.py", line 60, in __init__
    raise TypeError('Parser must be a string or character stream, not '
TypeError: Parser must be a string or character stream, not datetime

Редактировать 2: def, который форматирует дату и время:

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

1 Ответ

1 голос
/ 07 августа 2020

Из трассировки видно, что исключение возникает во время рендеринга шаблона. Фильтр форматирования даты в

<h4>{{ show.start_time|datetime('full') }}</h4>

, похоже, ожидает только строковые значения и пытается проанализировать их до datetime. С другой стороны, ваши модели используют правильный тип временной метки, поэтому атрибут show.start_time уже является экземпляром datetime. Один из способов исправить это несоответствие - изменить фильтр форматирования, чтобы он также принимал значения datetime:

def format_datetime(value, format='medium'):
    # instead of just date = dateutil.parser.parse(value)
    if isinstance(value, str):
        date = dateutil.parser.parse(value)
    else:
        date = value
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...