diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 61fd2be40b..4afe28806d 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -14,6 +14,7 @@ from django.utils.encoding import force_unicode from django.utils.tree import Node from django.db import connections, DEFAULT_DB_ALIAS from django.db.models import signals +from django.db.models.expressions import ExpressionNode from django.db.models.fields import FieldDoesNotExist from django.db.models.query_utils import InvalidQuery from django.db.models.sql import aggregates as base_aggregates_module @@ -1064,7 +1065,7 @@ class Query(object): value = True elif callable(value): value = value() - elif hasattr(value, 'evaluate'): + elif isinstance(value, ExpressionNode): # If value is a query expression, evaluate it value = SQLEvaluator(value, self) having_clause = value.contains_aggregate diff --git a/tests/regressiontests/model_regress/tests.py b/tests/regressiontests/model_regress/tests.py index 07ad8faea1..77bb4f23eb 100644 --- a/tests/regressiontests/model_regress/tests.py +++ b/tests/regressiontests/model_regress/tests.py @@ -164,8 +164,23 @@ class ModelTests(TestCase): 1 ) + class ModelValidationTest(TestCase): def test_pk_validation(self): one = NonAutoPK.objects.create(name="one") again = NonAutoPK(name="one") self.assertRaises(ValidationError, again.validate_unique) + + +class EvaluateMethodTest(TestCase): + """ + Regression test for #13640: cannot filter by objects with 'evaluate' attr + """ + + def test_model_with_evaluate_method(self): + """ + Ensures that you can filter by objects that have an 'evaluate' attr + """ + dept = Department.objects.create(pk=1, name='abc') + dept.evaluate = 'abc' + Worker.objects.filter(department=dept)