I am learning from Miguel Grinberg's excellent Flask Mega-Tutorial and writing an app which tracks the items in two freezers. Dates are saved in UTC in the database but I want to display them in the user's local format in the browser, using flask_moment, as described in https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xii-dates-and-times.

models.py

class Item(db.Model):
    id: so.Mapped[int] = so.mapped_column(primary_key=True)
...
    use_by_date: so.Mapped[date] = so.mapped_column(index=True)
...
    def __repr__(self):
        return f"{self.description}, {self.amount}, Use by {self.use_by_date}"


routes.py

@bp.route('/search_items_by_description', methods=['GET', 'POST'])
@login_required
def search_items_by_description():
    form = SearchItemsByDescriptionForm()
    if form.validate_on_submit():
...
        items = db.session.scalars(items_query).all()
        title = f"Items with '{search_description}' in their Description"
        return render_template('main/list_items.html', items=items, title=title)
    return render_template('main/search_items_by_description.html', form=form)


@bp.route('/search_items_by_use_by_date', methods=['GET', 'POST'])
@login_required
def search_items_by_use_by_date():
    form = SearchItemsByUseByDateForm()
    if form.validate_on_submit():
...
        items = db.session.scalars(items_query).all()
        title = f"Items with Use By Date older than {search_date}"
        return render_template('main/list_items.html', items=items, title=title)
    return render_template('main/search_items_by_use_by_date.html', form=form)


@bp.route('/search_items_by_location', methods=['GET', 'POST'])
@login_required
def search_items_by_location():
    form = SearchItemsByLocationForm()
    if form.validate_on_submit():
...
        items = db.session.scalars(items_query).all()
        title = f"Items in {location_name} location"
...
        return render_template('main/list_items.html', items=items, title=title)
    return render_template('main/search_items_by_location.html', form=form)


list_items.html template

{% extends "main/base.html" %}
{% import "main/bootstrap_wtf.html" as wtf %}

{% block content %}
    <div class="page-header">

        <h1>{{ title }}</h1>
        <table class="table table-bordered border-primary">
            <thead>
                <tr>
...
                    <th>Use By Date</th>
...
                </tr>
            </thead>
            <tbody>
            {% for item in items %}
                <tr>
...
                    <td>{{ moment(item.use_by_date).format('L') }}</td>
...
                </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
{% endblock %}

I have several forms which allow search by different criteria, with the resulting items being displayed using a common list_items.html template. Only the title changes, according to the search criterion which was made. I have had success displaying the use_by_date of each of the items but I have not found a way to format a search_date passed as part of the title in the search_items_by_use_by_date case. At present, the web client shows this:

Items with Use By Date older than 2025-11-25

Description        Amount   Location        Use By Date
Christmas pudding   1       Second shelf    31/12/2026
Garlic bread        1   Top shelf       31/12/2026

Sorry about the formatting but I hope the problem is clear - the date in the title is the default format (which I don't want) and the date for each item is in local format (which I do want).

I know I could write a special use_by_date_list_items.html template and pass the search_date as a keyword argument but I'm curious. Is there some way of using moment to format a date passed as part of the title but not in a separate keyword?

1 Reply 1

I think you can also format the date within the respective endpoint. However, since the output of format() produces HTML code, it's necessary to bypass Jinja's automatic escaping.

Your code would look something like this.

from flask_moment import moment
from markupsafe import Markup
# ...
title = Markup(f'Items with Use By Date older than {moment(search_date).format('L')}')

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.