I'm trying to have a webpage show all of the upcoming shows listed in a database, along with a bunch of info about each show that's stored in venue and artist tables respectively. I query the Show table, and then for each row in that result I link the Artist and Venue tables. Because the error has something to do with datetime, I'm assuming the error is something to do with either if show.start_time > current_time: or "start_time": show.start_time but the error doesn't pin down where it is. I tried converting both current_time and show.start_time to a string just to see if that worked, but no luck. What am I doing wrong?
@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)
If it helps, here are the models associated with it:
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)
Edit: Including full traceback.
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
Edit 2: def that formats datetime:
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
shows.htmltemplate, where it has<h4>{{ show.start_time|datetime('full') }}</h4>.show.start_timeis adatetime, which apparently thedatetime('full')filter or so does not like, because it seems to be trying to parse the value as if it were a string.datetime()filter yourself, or is it provided by the template library or the framework? A somewhat ugly solution would be to formatshow.start_timeas a string before passing to the template, but that's band-aid, and you would have to know what format the parser is happy with (ISO 8601 is a good guess).