ORM Lens

DOL021 — datetime.now() should be timezone.now()

Default severity: warning · Applicability: suggestion · Category: datetime

Detects bare datetime.now() calls (the from datetime import datetime style; attribute forms like datetime.datetime.now() are not matched). datetime.now() returns a naive datetime in server-local time. Under USE_TZ=True, saving one to a DateTimeField triggers RuntimeWarning: DateTimeField received a naive datetime, and comparisons against the aware datetimes Django produces elsewhere raise TypeError. The idiomatic clock is django.utils.timezone.now(), which follows the setting — aware UTC when USE_TZ=True, naive local time when it is False — and so is the correct call either way. The QuickFix (“Replace with timezone.now()”) rewrites the call only; add the timezone import yourself. It is a suggestion because projects that explicitly run USE_TZ=False may want naive datetimes.

Which projects actually have USE_TZ=True? Two separate things are easy to conflate. The framework default in django.conf.global_settings was False up to and including Django 4.2, and became True only in Django 5.0. Separately, since Django 4.0 the startproject template writes USE_TZ = True into the settings file it generates. So a project created on 4.0+ is timezone-aware because the template opted it in, while an existing project upgraded to 4.x stays on False until someone sets it. On Django 4.x, check the setting rather than assuming it.

Bad

from datetime import datetime

order.confirmed_at = datetime.now()

Good

from django.utils import timezone

order.confirmed_at = timezone.now()

Suppress

# orm-lens-disable-next-line DOL021

Or per-workspace in .vscode/settings.json: {"djangoOrmLens.rules": {"DOL021": "off"}}.