Commit 65246de7 authored by Michał Modzelewski's avatar Michał Modzelewski Committed by Tim Graham
Browse files

Fixed #24031 -- Added CASE expressions to the ORM.

parent aa8ee6a5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -475,6 +475,7 @@ answer newbie questions, and generally made Django that much better:
    Michael Thornhill <michael.thornhill@gmail.com>
    Michal Chruszcz <troll@pld-linux.org>
    michal@plovarna.cz
    Michał Modzelewski <michal.modzelewski@gmail.com>
    Mihai Damian <yang_damian@yahoo.com>
    Mihai Preda <mihai_preda@yahoo.com>
    Mikaël Barbero <mikael.barbero nospam at nospam free.fr>
+8 −0
Original line number Diff line number Diff line
@@ -821,6 +821,14 @@ class BaseDatabaseOperations(object):
        """
        return "SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s"

    def unification_cast_sql(self, output_field):
        """
        Given a field instance, returns the SQL necessary to cast the result of
        a union to that type. Note that the resulting string should contain a
        '%s' placeholder for the expression being cast.
        """
        return '%s'

    def date_extract_sql(self, lookup_type, field_name):
        """
        Given a lookup_type of 'year', 'month' or 'day', returns the SQL that
+12 −0
Original line number Diff line number Diff line
@@ -5,6 +5,18 @@ from django.db.backends import BaseDatabaseOperations


class DatabaseOperations(BaseDatabaseOperations):
    def unification_cast_sql(self, output_field):
        internal_type = output_field.get_internal_type()
        if internal_type in ("GenericIPAddressField", "IPAddressField", "TimeField", "UUIDField"):
            # PostgreSQL will resolve a union as type 'text' if input types are
            # 'unknown'.
            # http://www.postgresql.org/docs/9.4/static/typeconv-union-case.html
            # These fields cannot be implicitly cast back in the default
            # PostgreSQL configuration so we need to explicitly cast them.
            # We must also remove components of the type within brackets:
            # varchar(255) -> varchar.
            return 'CAST(%%s AS %s)' % output_field.db_type(self.connection).split('(')[0]
        return '%s'

    def date_extract_sql(self, lookup_type, field_name):
        # http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
+1 −1
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@ import warnings

from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured  # NOQA
from django.db.models.query import Q, QuerySet, Prefetch  # NOQA
from django.db.models.expressions import ExpressionNode, F, Value, Func  # NOQA
from django.db.models.expressions import ExpressionNode, F, Value, Func, Case, When  # NOQA
from django.db.models.manager import Manager  # NOQA
from django.db.models.base import Model  # NOQA
from django.db.models.aggregates import *  # NOQA
+2 −2
Original line number Diff line number Diff line
@@ -14,8 +14,9 @@ class Aggregate(Func):
    contains_aggregate = True
    name = None

    def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False):
    def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
        assert len(self.source_expressions) == 1
        # Aggregates are not allowed in UPDATE queries, so ignore for_save
        c = super(Aggregate, self).resolve_expression(query, allow_joins, reuse, summarize)
        if c.source_expressions[0].contains_aggregate and not summarize:
            name = self.source_expressions[0].name
@@ -101,7 +102,6 @@ class Count(Aggregate):
    def __init__(self, expression, distinct=False, **extra):
        if expression == '*':
            expression = Value(expression)
            expression._output_field = IntegerField()
        super(Count, self).__init__(
            expression, distinct='DISTINCT ' if distinct else '', output_field=IntegerField(), **extra)

Loading