Commit 23048d18 authored by Adam Chainz's avatar Adam Chainz Committed by Tim Graham
Browse files

Fixed #24866 -- Added Now() database function

parent 002b3d87
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
"""
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'

+15 −0
Original line number Diff line number Diff line
@@ -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
------

+3 −0
Original line number Diff line number Diff line
@@ -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
^^^^

+40 −1
Original line number Diff line number Diff line
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
        )