mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	[2.0.x] Fixed #28863 -- Fixed filter on annotation that contains Q.
Backport of cf12257db2 from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							4dc35e126d
						
					
				
				
					commit
					70da0420c2
				
			| @@ -26,6 +26,7 @@ class WhereNode(tree.Node): | |||||||
|     contains_aggregate attribute. |     contains_aggregate attribute. | ||||||
|     """ |     """ | ||||||
|     default = AND |     default = AND | ||||||
|  |     resolved = False | ||||||
|  |  | ||||||
|     def split_having(self, negated=False): |     def split_having(self, negated=False): | ||||||
|         """ |         """ | ||||||
| @@ -108,7 +109,7 @@ class WhereNode(tree.Node): | |||||||
|                 # around the inner SQL in the negated case, even if the |                 # around the inner SQL in the negated case, even if the | ||||||
|                 # inner SQL contains just a single expression. |                 # inner SQL contains just a single expression. | ||||||
|                 sql_string = 'NOT (%s)' % sql_string |                 sql_string = 'NOT (%s)' % sql_string | ||||||
|             elif len(result) > 1: |             elif len(result) > 1 or self.resolved: | ||||||
|                 sql_string = '(%s)' % sql_string |                 sql_string = '(%s)' % sql_string | ||||||
|         return sql_string, result_params |         return sql_string, result_params | ||||||
|  |  | ||||||
| @@ -181,6 +182,11 @@ class WhereNode(tree.Node): | |||||||
|     def is_summary(self): |     def is_summary(self): | ||||||
|         return any(child.is_summary for child in self.children) |         return any(child.is_summary for child in self.children) | ||||||
|  |  | ||||||
|  |     def resolve_expression(self, *args, **kwargs): | ||||||
|  |         clone = self.clone() | ||||||
|  |         clone.resolved = True | ||||||
|  |         return clone | ||||||
|  |  | ||||||
|  |  | ||||||
| class NothingNode: | class NothingNode: | ||||||
|     """A node that matches nothing.""" |     """A node that matches nothing.""" | ||||||
|   | |||||||
| @@ -73,6 +73,15 @@ class BasicExpressionsTests(TestCase): | |||||||
|             ], |             ], | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |     @unittest.skipIf(connection.vendor == 'oracle', "Oracle doesn't support using boolean type in SELECT") | ||||||
|  |     def test_filtering_on_annotate_that_uses_q(self): | ||||||
|  |         self.assertEqual( | ||||||
|  |             Company.objects.annotate( | ||||||
|  |                 num_employees_check=ExpressionWrapper(Q(num_employees__gt=3), output_field=models.BooleanField()) | ||||||
|  |             ).filter(num_employees_check=True).count(), | ||||||
|  |             2, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|     def test_filter_inter_attribute(self): |     def test_filter_inter_attribute(self): | ||||||
|         # We can filter on attribute relationships on same model obj, e.g. |         # We can filter on attribute relationships on same model obj, e.g. | ||||||
|         # find companies where the number of employees is greater |         # find companies where the number of employees is greater | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user