Django

Session

>>> from django.contrib.sessions.models import Session
>>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
>>> s.expire_date
datetime.datetime(2005, 8, 20, 13, 35, 12)
>>> s.session_data
'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
>>> s.get_decoded()
{'user_id': 42}
>>> from django.contrib.sessions.backends.db import SessionStore
>>> s = SessionStore()
>>> s_data = ".eJxVjEEKwjAQAP-yZymbtomJJ_UjYTddqWhbyTaoiH-3RRC8DjPzgiyDDCw5DgK7ORfZQKQy97HoAkdaMQTyLbNhzxjarjaek_O1NQFdwpN1-7WorlOiK_z1TOkiYxfrZaJCfeGKSaWilKYyzlodFvX4ldZSRfU8jVEet3N-ws5h6xE3cCPV-5S7n_ADPWkfL7K4wLY2fApbRkOI6H0jDTvDNtjGNMbB-wMgXU_Z:1rGcFf:4Y53efIteKjKKAkWbOHhT3D6n3Yk0Z_vca2yDP8N-Dc"
>>> decoded_data = s.decode(s_data)

Database

手动触发数据库事务的 commit 提交

from django.db import transaction
from seahub.utils import gen_token

token = gen_token(30) + gen_token(30)
transaction.set_autocommit(False)
try:
    t = ClientSSOToken(token=token)
    t.save()
    transaction.commit()
except Exception as e:
    logger.error(e)
    transaction.rollback()
finally:
    transaction.set_autocommit(True)

USE_TZ and TIME_ZONE

当配置了 USE_TZ = True

数据库中记录 UTC 时间,Django 从数据库中取出时间后,会生成 tzinfoUTCdatetime 对象。

当没有配置 USE_TZ = True

数据库中记录的是根据 TIME_ZONE 得到的本地时间,Django 从数据库中取出时间后,会生成 tzinfoNonedatetime 对象。

举例说明

比如,在 北京时间 2021-04-10 14点左右 创建的数据,在数据中存的时间为:

数据库中存的时间 配置 说明
2021-04-10 13:53:40 TIME_ZONE = 'Asia/Shanghai' 存的是上海当地时间
2021-04-10 05:57:18 USE_TZ = True and TIME_ZONE = 'Asia/Shanghai' 忽略 TIME_ZONE 配置,存的是 UTC 时间
2021-04-10 01:05:29 TIME_ZONE = America/Chicago 存的是芝加哥当地时间

问题及解决方案

TypeError: can’t compare offset-naive and offset-aware datetimes

对比两个 datetime 对象时,如果一个有 tzinfo、一个没有 tzinfo 则会报以上错误,解决方法:

datetime 对象统一 make_naivemake_aware 也可以)后,再对比。

from django.utils.timezone import make_naive, is_aware

# before make_naive
# 2021-04-09 05:32:30+00:00
# tzinfo: UTC

# after make_naive
# 2021-04-09 13:32:30
# tzinfo: None

if is_aware(last_login_time):
    last_login_time = make_naive(last_login_time)