Fixed #24866 -- Added Now() database function

This commit is contained in:
Adam Chainz 2015-05-29 15:54:10 +01:00 committed by Tim Graham
parent 002b3d87b5
commit 23048d186c
4 changed files with 75 additions and 2 deletions

View File

@ -1,7 +1,7 @@
""" """
Classes that represent database functions. 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 from django.db.models.expressions import Func, Value
@ -103,6 +103,22 @@ class Lower(Func):
super(Lower, self).__init__(expression, **extra) 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): class Substr(Func):
function = 'SUBSTRING' function = 'SUBSTRING'

View File

@ -117,6 +117,21 @@ Usage example::
>>> print(author.name_lower) >>> print(author.name_lower)
margaret smith 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 Substr
------ ------

View File

@ -240,6 +240,9 @@ Models
* Added the :lookup:`date` lookup to :class:`~django.db.models.DateTimeField` * Added the :lookup:`date` lookup to :class:`~django.db.models.DateTimeField`
to allow querying the field by only the date portion. 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 CSRF
^^^^ ^^^^

View File

@ -1,8 +1,10 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import datetime, timedelta
from django.db.models import CharField, TextField, Value as V from django.db.models import CharField, TextField, Value as V
from django.db.models.functions import ( 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.test import TestCase
from django.utils import six, timezone from django.utils import six, timezone
@ -311,3 +313,40 @@ class FunctionTests(TestCase):
], ],
lambda a: a.name 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
)