mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #26153 -- Reallowed Q-objects in ForeignObject.get_extra_descriptor_filter().
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							1d86d4c72b
						
					
				
				
					commit
					353aecbf8c
				
			| @@ -8,6 +8,7 @@ from django.apps import apps | ||||
| from django.core import checks, exceptions | ||||
| from django.db import connection, router | ||||
| from django.db.backends import utils | ||||
| from django.db.models import Q | ||||
| from django.db.models.deletion import CASCADE, SET_DEFAULT, SET_NULL | ||||
| from django.db.models.query_utils import PathInfo | ||||
| from django.db.models.utils import make_model_tuple | ||||
| @@ -337,8 +338,13 @@ class RelatedField(Field): | ||||
|             rh_field.attname: getattr(obj, lh_field.attname) | ||||
|             for lh_field, rh_field in self.related_fields | ||||
|         } | ||||
|         base_filter.update(self.get_extra_descriptor_filter(obj) or {}) | ||||
|         return base_filter | ||||
|         descriptor_filter = self.get_extra_descriptor_filter(obj) | ||||
|         base_q = Q(**base_filter) | ||||
|         if isinstance(descriptor_filter, dict): | ||||
|             return base_q & Q(**descriptor_filter) | ||||
|         elif descriptor_filter: | ||||
|             return base_q & descriptor_filter | ||||
|         return base_q | ||||
|  | ||||
|     @property | ||||
|     def swappable_setting(self): | ||||
|   | ||||
| @@ -166,7 +166,7 @@ class ForwardManyToOneDescriptor(object): | ||||
|                 rel_obj = None | ||||
|             else: | ||||
|                 qs = self.get_queryset(instance=instance) | ||||
|                 qs = qs.filter(**self.field.get_reverse_related_filter(instance)) | ||||
|                 qs = qs.filter(self.field.get_reverse_related_filter(instance)) | ||||
|                 # Assuming the database enforces foreign keys, this won't fail. | ||||
|                 rel_obj = qs.get() | ||||
|                 # If this is a one-to-one relation, set the reverse accessor | ||||
|   | ||||
| @@ -17,3 +17,7 @@ Bugfixes | ||||
|  | ||||
| * Added system checks for query name clashes of hidden relationships | ||||
|   (:ticket:`26162`). | ||||
|  | ||||
| * Fixed a regression for cases where | ||||
|   ``ForeignObject.get_extra_descriptor_filter()`` returned a ``Q`` object | ||||
|   (:ticket:`26153`). | ||||
|   | ||||
| @@ -44,6 +44,11 @@ class ActiveTranslationField(models.ForeignObject): | ||||
|         setattr(cls, self.name, ArticleTranslationDescriptor(self)) | ||||
|  | ||||
|  | ||||
| class ActiveTranslationFieldWithQ(ActiveTranslationField): | ||||
|     def get_extra_descriptor_filter(self, instance): | ||||
|         return models.Q(lang=get_language()) | ||||
|  | ||||
|  | ||||
| @python_2_unicode_compatible | ||||
| class Article(models.Model): | ||||
|     active_translation = ActiveTranslationField( | ||||
| @@ -54,6 +59,14 @@ class Article(models.Model): | ||||
|         on_delete=models.CASCADE, | ||||
|         null=True, | ||||
|     ) | ||||
|     active_translation_q = ActiveTranslationFieldWithQ( | ||||
|         'ArticleTranslation', | ||||
|         from_fields=['id'], | ||||
|         to_fields=['article'], | ||||
|         related_name='+', | ||||
|         on_delete=models.CASCADE, | ||||
|         null=True, | ||||
|     ) | ||||
|     pub_date = models.DateField() | ||||
|  | ||||
|     def __str__(self): | ||||
|   | ||||
| @@ -458,3 +458,16 @@ class TestModelCheckTests(SimpleTestCase): | ||||
|             ) | ||||
|  | ||||
|         self.assertEqual(Child._meta.get_field('parent').check(from_model=Child), []) | ||||
|  | ||||
|  | ||||
| class TestExtraJoinFilterQ(TestCase): | ||||
|     @translation.override('fi') | ||||
|     def test_extra_join_filter_q(self): | ||||
|         a = Article.objects.create(pub_date=datetime.datetime.today()) | ||||
|         ArticleTranslation.objects.create(article=a, lang='fi', title='title', body='body') | ||||
|         qs = Article.objects.all() | ||||
|         with self.assertNumQueries(2): | ||||
|             self.assertEqual(qs[0].active_translation_q.title, 'title') | ||||
|         qs = qs.select_related('active_translation_q') | ||||
|         with self.assertNumQueries(1): | ||||
|             self.assertEqual(qs[0].active_translation_q.title, 'title') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user