Fixed #24866 -- Added Now() database function
This commit is contained in:
parent
002b3d87b5
commit
23048d186c
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in New Issue