From 89a3e0ef52aa70cba4da0b87d298d53f97cd43e1 Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Thu, 21 Dec 2017 16:53:46 +0100
Subject: [PATCH] Allow to pass created_at/updated_at fields as strings

Strings are automatically converted to datetime object.
Note that datetime are stored without timezone in the database (in UTC).
---
 app/models.py |  9 +++++++++
 app/utils.py  | 12 ++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/app/models.py b/app/models.py
index 99e32c9..265e19c 100644
--- a/app/models.py
+++ b/app/models.py
@@ -262,6 +262,15 @@ class CreatedMixin:
     def user(cls):
         return db.relationship('User')
 
+    def __init__(self, **kwargs):
+        # Automatically convert created_at/updated_at strings
+        # to datetime object
+        for key in ('created_at', 'updated_at'):
+            if key in kwargs:
+                if isinstance(kwargs[key], str):
+                    kwargs[key] = utils.parse_to_utc(kwargs[key])
+        super().__init__(**kwargs)
+
     def to_dict(self):
         return {
             'id': self.id,
diff --git a/app/utils.py b/app/utils.py
index 7f9c8b8..e2c78dc 100644
--- a/app/utils.py
+++ b/app/utils.py
@@ -13,6 +13,7 @@ import base64
 import datetime
 import io
 import sqlalchemy as sa
+import dateutil.parser
 from flask.globals import _app_ctx_stack, _request_ctx_stack
 from flask_login import current_user
 from flask_jwt_extended import get_current_user
@@ -168,3 +169,14 @@ def coerce_to_str_or_none(value):
     if not value or value == 'None':
         return None
     return str(value)
+
+
+def parse_to_utc(string):
+    """Convert a string to a datetime object with no timezone"""
+    d = dateutil.parser.parse(string)
+    if d.tzinfo is None:
+        # Assume this is UTC
+        return d
+    # Convert to UTC and remove timezone
+    d = d.astimezone(datetime.timezone.utc)
+    return d.replace(tzinfo=None)
-- 
GitLab