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

Callable arguments were an untested and undocumented feature.
This commit is contained in:
Baptiste Mispelon 2013-12-18 16:59:08 +01:00
parent d34c8c338a
commit f1b3ab9c21
4 changed files with 29 additions and 0 deletions

View File

@ -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

View File

@ -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
---

View File

@ -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.

View File

@ -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):