Commit f1b3ab9c authored by Baptiste Mispelon's avatar Baptiste Mispelon
Browse files

Fixed #11629 -- Deprecated callable arguments to queryset methods.

Callable arguments were an untested and undocumented feature.
parent d34c8c33
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ all about the internals of models in order to get the information it needs.

from collections import OrderedDict
import copy
import warnings

from django.utils.encoding import force_text
from django.utils.tree import Node
@@ -1036,6 +1037,9 @@ class Query(object):
            lookup_type = 'isnull'
            value = True
        elif callable(value):
            warnings.warn(
                "Passing callable arguments to queryset is deprecated.",
                PendingDeprecationWarning, stacklevel=2)
            value = value()
        elif isinstance(value, ExpressionNode):
            # If value is a query expression, evaluate it
+2 −0
Original line number Diff line number Diff line
@@ -226,6 +226,8 @@ these changes.
  loading APIs instead. Several undocumented methods of the ``AppCache`` class
  will also be removed.

* Passing callable arguments to querysets will no longer be possible.

2.0
---

+11 −0
Original line number Diff line number Diff line
@@ -869,3 +869,14 @@ Geo Sitemaps

Google has retired support for the Geo Sitemaps format. Hence Django support
for Geo Sitemaps is deprecated and will be removed in Django 1.8.

Passing callable arguments to queryset methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Callable arguments for querysets were an undocumented feature that was
unreliable. It's been deprecated and will be removed in Django 1.9.

Callable arguments were evaluated when a queryset was constructed rather than
when it was evaluated, thus this feature didn't offer any benefit compared to
evaluating arguments before passing them to queryset and created confusion that
the arguments may have been evaluated at query time.
+12 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import datetime
from operator import attrgetter
import pickle
import unittest
import warnings

from django.core.exceptions import FieldError
from django.db import DatabaseError, connection, connections, DEFAULT_DB_ALIAS
@@ -1139,6 +1140,17 @@ class Queries1Tests(BaseQuerysetTest):
            ['<Author: a1>', '<Author: a2>', '<Author: a3>', '<Author: a4>']
        )

    def test_callable_args(self):
        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter('always')
            qs = Tag.objects.filter(name__startswith=lambda: 't')
            self.assertQuerysetEqual(
                qs,
                ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
            )
            self.assertEqual(len(w), 1)
            self.assertTrue(issubclass(w[0].category, PendingDeprecationWarning))


class Queries2Tests(TestCase):
    def setUp(self):