diff --git a/README.md b/README.md index 11cec5f..3764755 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,17 @@ pip install django-apscheduler Usage ----- -* Add ``django_apscheduler`` to ``INSTALLED_APPS`` in your Django project settings: +* Add ``django_apscheduler`` to ``INSTALLED_APPS`` in your Django project settings, You can also specify a different +format for displaying runtime timestamps in the Django admin site using ``APSCHEDULER_DATETIME_FORMAT``: ```python INSTALLED_APPS = ( ... django_apscheduler, ) + + APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s a" # Default + ``` * Run migrations: diff --git a/django_apscheduler/admin.py b/django_apscheduler/admin.py index 2fd07b8..0a65f3a 100644 --- a/django_apscheduler/admin.py +++ b/django_apscheduler/admin.py @@ -5,6 +5,7 @@ from django.utils.timezone import now from django_apscheduler.models import DjangoJob, DjangoJobExecution +from django_apscheduler import util def execute_now(ma, r, qs): @@ -32,7 +33,7 @@ def get_queryset(self, request): return super(DjangoJobAdmin, self).get_queryset(request) def next_run_time_sec(self, obj): - return obj.next_run_time.strftime("%Y-%m-%d %H:%M:%S") + return util.localize(obj.next_run_time) def average_duration(self, obj): return self._durations.get(obj.id) or 0 @@ -45,7 +46,7 @@ class DjangoJobExecutionAdmin(admin.ModelAdmin): list_filter = ["job__name", "run_time", "status"] def run_time_sec(self, obj): - return obj.run_time.strftime("%Y-%m-%d %H:%M:%S") + return util.localize(obj.run_time) def get_queryset(self, request): return super(DjangoJobExecutionAdmin, self).get_queryset( diff --git a/django_apscheduler/util.py b/django_apscheduler/util.py index f0ec480..0a61ee7 100644 --- a/django_apscheduler/util.py +++ b/django_apscheduler/util.py @@ -1,5 +1,6 @@ from django.conf import settings -from django.utils.timezone import is_aware, is_naive, make_aware, make_naive +from django.utils import formats +from django.utils import timezone def serialize_dt(dt): @@ -8,12 +9,23 @@ def serialize_dt(dt): :param dt: :return: """ - if not settings.USE_TZ and dt and is_aware(dt): - return make_naive(dt) + if not settings.USE_TZ and dt and timezone.is_aware(dt): + return timezone.make_naive(dt) return dt def deserialize_dt(dt): - if not settings.USE_TZ and dt and is_naive(dt): - return make_aware(dt) + if not settings.USE_TZ and dt and timezone.is_naive(dt): + return timezone.make_aware(dt) return dt + + +def get_format(): + return formats.get_format(getattr(settings, "APSCHEDULER_DATETIME_FORMAT", "N j, Y, f:s a")) + + +def localize(dt): + if settings.USE_TZ and dt and timezone.is_aware(dt): + dt = timezone.localtime(dt) + + return formats.date_format(dt, get_format()) diff --git a/setup.py b/setup.py index 3a1e1ce..75cf695 100644 --- a/setup.py +++ b/setup.py @@ -11,12 +11,10 @@ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", - "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules", "Framework :: Django", - "Framework :: Django :: 1.8", - "Framework :: Django :: 1.9", ], keywords='django apscheduler django-apscheduler', url='http://github.com/jarekwg/django-apscheduler', @@ -27,7 +25,7 @@ exclude=("tests", ) ), install_requires=[ - 'django>=1.8', + 'django>=1.11', 'apscheduler>=3.2.0', ], zip_safe=False diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..62b0a92 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,23 @@ +import pytest +from django.conf import settings + + +@pytest.fixture +def use_seconds_format(): + settings.APSCHEDULER_DATETIME_FORMAT = "N j, Y, f:s" + return settings.APSCHEDULER_DATETIME_FORMAT + + +@pytest.fixture +def use_tz(): + settings.APSCHEDULER_DATETIME_FORMAT = "H" # Only interested in hour + settings.USE_TZ = True + + return settings.APSCHEDULER_DATETIME_FORMAT + + +@pytest.fixture +def use_hour_format(): + settings.APSCHEDULER_DATETIME_FORMAT = "H" # Only interested in hour + + return settings.APSCHEDULER_DATETIME_FORMAT diff --git a/tests/test_util.py b/tests/test_util.py new file mode 100644 index 0000000..f1a15a9 --- /dev/null +++ b/tests/test_util.py @@ -0,0 +1,34 @@ +from datetime import datetime + +from django.utils import timezone + +from django_apscheduler import util + + +def test_get_format_default(): + assert util.get_format() == "N j, Y, f:s a" + + +def test_get_format_from_settings(use_seconds_format): + assert util.get_format() == use_seconds_format + + +def test_localize_naive(use_hour_format): + + dt = datetime.utcnow() + dt_hour = dt.strftime("%H") + + localized_dt_hour = util.localize(dt) + + assert localized_dt_hour == dt_hour + + +def test_localize_aware(use_tz): + utc_dt = timezone.now() + + local_dt = timezone.localtime(utc_dt) + local_dt_hour = local_dt.strftime("%H") + + localized_dt_hour = util.localize(utc_dt) + + assert localized_dt_hour == local_dt_hour diff --git a/tox.ini b/tox.ini index f5509e2..0cdd36c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = {py36}-{dj1,dj18,dj2},{py27-dj1,dj18},{py35}-{dj1,dj18,dj2} +envlist = {py36}-{dj1,dj2},{py27-dj1},{py35}-{dj1,dj2} skipsdist = true [pytest] @@ -10,7 +10,6 @@ deps = pytest pytest-django pytest-cov mock - dj18: Django==1.8 dj1: Django<2.0.0 dj2: Django==2.*