Ticket #25556: expressions.diff

File expressions.diff, 6.3 KB (added by David Filipovic, 9 years ago)
  • django/db/models/expressions.py

    diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
    index d954005..fa132c6 100644
    a b class Date(Expression):  
    892892        return value
    893893
    894894
     895class DatePart(Date):
     896    """
     897    Add a partial date selection column.
     898
     899    Enables construction of complex date queries
     900    involving date fields with lookup types of:
     901    'year', 'month', 'day'. E.g.:
     902
     903    `MyModel.objects.filter(date1__month=DatePart('date2', 'month')`
     904    """
     905    def as_sql(self, compiler, connection):
     906        sql, params = self.col.as_sql(compiler, connection)
     907        assert not(params)
     908        return connection.ops.date_extract_sql(self.lookup_type, sql), []
     909
     910
    895911class DateTime(Expression):
    896912    """
    897913    Add a datetime selection column.
    class DateTime(Expression):  
    950966        return value
    951967
    952968
     969class DateTimePart(DateTime):
     970    """
     971    Add a partial datetime selection column.
     972
     973    Enables construction of complex date queries
     974    involving datetime fields with lookup types of:
     975    'year', 'month', 'day'. E.g.:
     976
     977    `MyModel.objects.filter(date1__month=DatePart('date2', 'month')`
     978    """
     979    def as_sql(self, compiler, connection):
     980        sql, params = self.col.as_sql(compiler, connection)
     981        assert not(params)
     982        return connection.ops.datetime_extract_sql(self.lookup_type, sql, self.tzname)
     983
     984
    953985class OrderBy(BaseExpression):
    954986    template = '%(expression)s %(ordering)s'
    955987
  • tests/expressions/tests.py

    diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
    index f688927..7af5aac 100644
    a b from django.db.models.aggregates import (  
    1111    Avg, Count, Max, Min, StdDev, Sum, Variance,
    1212)
    1313from django.db.models.expressions import (
    14     F, Case, Col, Date, DateTime, ExpressionWrapper, Func, OrderBy, Random,
    15     RawSQL, Ref, Value, When,
     14    F, Case, Col, Date, DatePart, DateTime, DateTimePart, ExpressionWrapper,
     15    Func, OrderBy, Random, RawSQL, Ref, Value, When,
    1616)
    1717from django.db.models.functions import (
    1818    Coalesce, Concat, Length, Lower, Substr, Upper,
    class ValueTests(TestCase):  
    897897        self.assertEqual(UUID.objects.get().uuid, uuid.UUID('12345678901234567890123456789012'))
    898898
    899899
     900class DatePartTests(TestCase):
     901
     902    def setUp(self):
     903        self.same_month_day = Experiment.objects.create(
     904            name='same_month_day_experiment',
     905            assigned=datetime.date(2014, 10, 15),
     906            completed=datetime.date(2015, 10, 15),
     907            estimated_time=datetime.timedelta(days=1),
     908            start=datetime.datetime.now(),
     909            end=datetime.datetime.now(),
     910        )
     911
     912        self.same_month = Experiment.objects.create(
     913            name='same_month_experiment',
     914            assigned=datetime.date(2014, 10, 1),
     915            completed=datetime.date(2015, 10, 12),
     916            estimated_time=datetime.timedelta(days=1),
     917            start=datetime.datetime.now(),
     918            end=datetime.datetime.now(),
     919        )
     920
     921        self.same_day = Experiment.objects.create(
     922            name='same_day_experiment',
     923            assigned=datetime.date(2013, 7, 15),
     924            completed=datetime.date(2015, 10, 15),
     925            estimated_time=datetime.timedelta(days=1),
     926            start=datetime.datetime.now(),
     927            end=datetime.datetime.now(),
     928        )
     929
     930    def test_datepart(self):
     931        same_day_experiments = Experiment.objects.filter(assigned__day=DatePart('completed', 'day'))
     932
     933        self.assertEqual(same_day_experiments.count(), 2)
     934        self.assertIn(self.same_day, same_day_experiments)
     935        self.assertIn(self.same_month_day, same_day_experiments)
     936
     937        same_month_experiments = Experiment.objects.filter(assigned__month=DatePart('completed', 'month'))
     938
     939        self.assertEqual(same_month_experiments.count(), 2)
     940        self.assertIn(self.same_month, same_month_experiments)
     941        self.assertIn(self.same_month_day, same_month_experiments)
     942
     943        same_month_day_experiment = Experiment.objects.get(
     944            assigned__day=DatePart('completed', 'day'),
     945            assigned__month=DatePart('completed', 'month'),
     946        )
     947
     948        self.assertEqual(self.same_month_day, same_month_day_experiment)
     949
     950
     951class DateTimePartTests(TestCase):
     952
     953    def setUp(self):
     954        self.same_month_day = Experiment.objects.create(
     955            name='same_month_day_experiment',
     956            assigned=datetime.date.today(),
     957            completed=datetime.date.today(),
     958            estimated_time=datetime.timedelta(days=1),
     959            start=datetime.datetime(2014, 7, 4, 12, 33, 15),
     960            end=datetime.datetime(2015, 7, 4, 10, 13, 12),
     961        )
     962
     963        self.same_month = Experiment.objects.create(
     964            name='same_month_experiment',
     965            assigned=datetime.date.today(),
     966            completed=datetime.date.today(),
     967            estimated_time=datetime.timedelta(days=1),
     968            start=datetime.datetime(2014, 6, 12, 7, 33, 15),
     969            end=datetime.datetime(2015, 6, 5, 11, 13, 12),
     970        )
     971
     972        self.same_day = Experiment.objects.create(
     973            name='same_day_experiment',
     974            assigned=datetime.date.today(),
     975            completed=datetime.date.today(),
     976            estimated_time=datetime.timedelta(days=1),
     977            start=datetime.datetime(2014, 10, 6, 4, 33, 15),
     978            end=datetime.datetime(2015, 3, 6, 1, 13, 12),
     979        )
     980
     981    def test_datetimepart(self):
     982        same_day_experiments = Experiment.objects.filter(start__day=DateTimePart('end', 'day'))
     983
     984        self.assertEqual(same_day_experiments.count(), 2)
     985        self.assertIn(self.same_day, same_day_experiments)
     986        self.assertIn(self.same_month_day, same_day_experiments)
     987
     988        same_month_experiments = Experiment.objects.filter(start__month=DateTimePart('end', 'month'))
     989
     990        self.assertEqual(same_month_experiments.count(), 2)
     991        self.assertIn(self.same_month, same_month_experiments)
     992        self.assertIn(self.same_month_day, same_month_experiments)
     993
     994        same_month_day_experiment = Experiment.objects.get(
     995            start__day=DatePart('end', 'day'),
     996            start__month=DatePart('end', 'month'),
     997        )
     998
     999        self.assertEqual(self.same_month_day, same_month_day_experiment)
     1000
     1001
    9001002class ReprTests(TestCase):
    9011003
    9021004    def test_expressions(self):
Back to Top