19 январь 2018 Python datetime RFC1123 Last-Modified


Использование даты в этом формате необходимо для обработки HTTP заголовка Last-Modified. Это когда сервер отдаёт дату изменения страницы в заголовке Last-Modified а затем клиет отправляе HEAD запрос с этим заголовком и датой и если страница не менялась, то ваш сервер отвечает 200 и отправляет пустое тело страницы. Это экономит и трафик и ресурсы процессора, а так же ускоряет повторную индексацию сайта и просто более технологично чем просто отдават страницы на каждый запрос.

Итак настроить дату обновления страницы в таком формате очень легко и делается это вот так:

class BaseClass(SQLAModel):
    __abstract__ = True
...
    updated_on =    Column(DateTime, default=func.now(), onupdate=func.now(), doc=_('дата редактирования'))
...

    def get_last_modified(self):
        return self.updated_on.strftime("%a, %d %B %Y %H:%M:%S GMT")

И всё будет прекрасно работать до тех пор пока вам не потребуется локализовать даты (это когда месяцы на русском). Для этого вы сделаете вот так где в __init__.py

...
import locale
...

locale.setlocale(locale.LC_ALL, 'ru_RU.UTF-8')

Возможно, раз вы используете babel, то у вас будет сменная локаль, это всё круто. Но этот системный вызов изменит поведение вашей get_last_modified и все ваши усилия по обработке Last-Modified приведут к тому, что появится вот такая ошибка

    TypeError: http header must be encodable in latin1

По-этому, формировать дату в RFC формате формате необходимо правильным образом, а именно вот так

from time import mktime
from wsgiref.handlers import format_date_time


class BaseClass(SQLAModel):
    __abstract__ = True
....
    updated_on =    Column(DateTime, default=func.now(), onupdate=func.now(), doc=_('дата редактирования'))

    def get_last_modified(self):
        stamp = mktime(self.updated_on.timetuple())
        return format_date_time(stamp)

Вот так вот всё просто.