summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Chainz <adam@adamj.eu>2015-05-29 15:54:10 +0100
committerTim Graham <timograham@gmail.com>2015-06-02 17:59:01 -0400
commit23048d186ce0041654a9f547fe3e7177efce3076 (patch)
tree931a4f7448be40aac015389a7255fb8d9042e891
parent002b3d87b5f1e35edcb6e14ce2e2827fc6c032a1 (diff)
Fixed #24866 -- Added Now() database function
-rw-r--r--django/db/models/functions.py18
-rw-r--r--docs/ref/models/database-functions.txt15
-rw-r--r--docs/releases/1.9.txt3
-rw-r--r--tests/db_functions/tests.py41
4 files changed, 75 insertions, 2 deletions
diff --git a/django/db/models/functions.py b/django/db/models/functions.py
index 613d396093..a39864e4b5 100644
--- a/django/db/models/functions.py
+++ b/django/db/models/functions.py
@@ -1,7 +1,7 @@
"""
Classes that represent database functions.
"""
-from django.db.models import IntegerField
+from django.db.models import DateTimeField, IntegerField
from django.db.models.expressions import Func, Value
@@ -103,6 +103,22 @@ class Lower(Func):
super(Lower, self).__init__(expression, **extra)
+class Now(Func):
+ template = 'CURRENT_TIMESTAMP'
+
+ def __init__(self, output_field=None, **extra):
+ if output_field is None:
+ output_field = DateTimeField()
+ super(Now, self).__init__(output_field=output_field, **extra)
+
+ def as_postgresql(self, compiler, connection):
+ # Postgres' CURRENT_TIMESTAMP means "the time at the start of the
+ # transaction". We use STATEMENT_TIMESTAMP to be cross-compatible with
+ # other databases.
+ self.template = 'STATEMENT_TIMESTAMP()'
+ return self.as_sql(compiler, connection)
+
+
class Substr(Func):
function = 'SUBSTRING'
diff --git a/docs/ref/models/database-functions.txt b/docs/ref/models/database-functions.txt
index cdd46ff1a2..b797e5f1df 100644
--- a/docs/ref/models/database-functions.txt
+++ b/docs/ref/models/database-functions.txt
@@ -117,6 +117,21 @@ Usage example::
>>> print(author.name_lower)
margaret smith
+Now
+---
+
+.. class:: Now()
+
+.. versionadded:: 1.9
+
+Returns the database server's current date and time when the query is executed.
+
+Usage example::
+
+ >>> from django.db.models.functions import Now
+ >>> Article.objects.filter(published__lte=Now())
+ [<Article: How to Django>]
+
Substr
------
diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt
index bca086b207..192da111c2 100644
--- a/docs/releases/1.9.txt
+++ b/docs/releases/1.9.txt
@@ -240,6 +240,9 @@ Models
* Added the :lookup:`date` lookup to :class:`~django.db.models.DateTimeField`
to allow querying the field by only the date portion.
+* Added the :class:`~django.db.models.functions.Now` database function, which
+ returns the current date and time.
+
CSRF
^^^^
diff --git a/tests/db_functions/tests.py b/tests/db_functions/tests.py
index f07e8770f0..1df9800f13 100644
--- a/tests/db_functions/tests.py
+++ b/tests/db_functions/tests.py
@@ -1,8 +1,10 @@
from __future__ import unicode_literals
+from datetime import datetime, timedelta
+
from django.db.models import CharField, TextField, Value as V
from django.db.models.functions import (
- Coalesce, Concat, Length, Lower, Substr, Upper,
+ Coalesce, Concat, Length, Lower, Now, Substr, Upper,
)
from django.test import TestCase
from django.utils import six, timezone
@@ -311,3 +313,40 @@ class FunctionTests(TestCase):
],
lambda a: a.name
)
+
+ def test_now(self):
+ ar1 = Article.objects.create(
+ title='How to Django',
+ text=lorem_ipsum,
+ written=timezone.now(),
+ )
+ ar2 = Article.objects.create(
+ title='How to Time Travel',
+ text=lorem_ipsum,
+ written=timezone.now(),
+ )
+
+ num_updated = Article.objects.filter(id=ar1.id, published=None).update(published=Now())
+ self.assertEqual(num_updated, 1)
+
+ num_updated = Article.objects.filter(id=ar1.id, published=None).update(published=Now())
+ self.assertEqual(num_updated, 0)
+
+ ar1.refresh_from_db()
+ self.assertIsInstance(ar1.published, datetime)
+
+ ar2.published = Now() + timedelta(days=2)
+ ar2.save()
+ ar2.refresh_from_db()
+ self.assertIsInstance(ar2.published, datetime)
+
+ self.assertQuerysetEqual(
+ Article.objects.filter(published__lte=Now()),
+ ['How to Django'],
+ lambda a: a.title
+ )
+ self.assertQuerysetEqual(
+ Article.objects.filter(published__gt=Now()),
+ ['How to Time Travel'],
+ lambda a: a.title
+ )