#220 Pass hints to returned queryset in PolymorphicManager.get_queryset.
parent
2a599b5f99
commit
f1735a8bea
|
|
@ -32,7 +32,7 @@ class PolymorphicManager(models.Manager):
|
||||||
super(PolymorphicManager, self).__init__(*args, **kwrags)
|
super(PolymorphicManager, self).__init__(*args, **kwrags)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = self.queryset_class(self.model, using=self._db)
|
qs = self.queryset_class(self.model, using=self._db, hints=self._hints)
|
||||||
if self.model._meta.proxy:
|
if self.model._meta.proxy:
|
||||||
qs = qs.instance_of(self.model)
|
qs = qs.instance_of(self.model)
|
||||||
return qs
|
return qs
|
||||||
|
|
|
||||||
|
|
@ -112,8 +112,8 @@ class PolymorphicQuerySet(QuerySet):
|
||||||
|
|
||||||
def _filter_or_exclude(self, negate, *args, **kwargs):
|
def _filter_or_exclude(self, negate, *args, **kwargs):
|
||||||
"We override this internal Django functon as it is used for all filter member functions."
|
"We override this internal Django functon as it is used for all filter member functions."
|
||||||
q_objects = translate_polymorphic_filter_definitions_in_args(self.model, args, using=self._db) # the Q objects
|
q_objects = translate_polymorphic_filter_definitions_in_args(self.model, args, using=self.db) # the Q objects
|
||||||
additional_args = translate_polymorphic_filter_definitions_in_kwargs(self.model, kwargs, using=self._db) # filter_field='data'
|
additional_args = translate_polymorphic_filter_definitions_in_kwargs(self.model, kwargs, using=self.db) # filter_field='data'
|
||||||
return super(PolymorphicQuerySet, self)._filter_or_exclude(negate, *(list(q_objects) + additional_args), **kwargs)
|
return super(PolymorphicQuerySet, self)._filter_or_exclude(negate, *(list(q_objects) + additional_args), **kwargs)
|
||||||
|
|
||||||
def order_by(self, *args, **kwargs):
|
def order_by(self, *args, **kwargs):
|
||||||
|
|
@ -309,7 +309,7 @@ class PolymorphicQuerySet(QuerySet):
|
||||||
# - also record the correct result order in "ordered_id_list"
|
# - also record the correct result order in "ordered_id_list"
|
||||||
# - store objects that already have the correct class into "results"
|
# - store objects that already have the correct class into "results"
|
||||||
base_result_objects_by_id = {}
|
base_result_objects_by_id = {}
|
||||||
content_type_manager = ContentType.objects.db_manager(self._db)
|
content_type_manager = ContentType.objects.db_manager(self.db)
|
||||||
self_model_class_id = content_type_manager.get_for_model(self.model, for_concrete_model=False).pk
|
self_model_class_id = content_type_manager.get_for_model(self.model, for_concrete_model=False).pk
|
||||||
self_concrete_model_class_id = content_type_manager.get_for_model(self.model, for_concrete_model=True).pk
|
self_concrete_model_class_id = content_type_manager.get_for_model(self.model, for_concrete_model=True).pk
|
||||||
|
|
||||||
|
|
@ -345,7 +345,7 @@ class PolymorphicQuerySet(QuerySet):
|
||||||
# Then we copy the extra() select fields from the base objects to the real objects.
|
# Then we copy the extra() select fields from the base objects to the real objects.
|
||||||
# TODO: defer(), only(): support for these would be around here
|
# TODO: defer(), only(): support for these would be around here
|
||||||
for real_concrete_class, idlist in idlist_per_model.items():
|
for real_concrete_class, idlist in idlist_per_model.items():
|
||||||
real_objects = real_concrete_class.base_objects.db_manager(self._db).filter(**{
|
real_objects = real_concrete_class.base_objects.db_manager(self.db).filter(**{
|
||||||
('%s__in' % pk_name): idlist,
|
('%s__in' % pk_name): idlist,
|
||||||
})
|
})
|
||||||
real_objects.query.select_related = self.query.select_related # copy select related configuration to new qs
|
real_objects.query.select_related = self.query.select_related # copy select related configuration to new qs
|
||||||
|
|
|
||||||
|
|
@ -429,9 +429,6 @@ class PolymorphicTests(TestCase):
|
||||||
"""
|
"""
|
||||||
The test suite
|
The test suite
|
||||||
"""
|
"""
|
||||||
|
|
||||||
multi_db = True
|
|
||||||
|
|
||||||
def test_annotate_aggregate_order(self):
|
def test_annotate_aggregate_order(self):
|
||||||
# create a blog of type BlogA
|
# create a blog of type BlogA
|
||||||
# create two blog entries in BlogA
|
# create two blog entries in BlogA
|
||||||
|
|
@ -1182,6 +1179,30 @@ class PolymorphicTests(TestCase):
|
||||||
result = DateModel.objects.annotate(val=DateTime('date', 'day', utc))
|
result = DateModel.objects.annotate(val=DateTime('date', 'day', utc))
|
||||||
self.assertEqual(list(result), [])
|
self.assertEqual(list(result), [])
|
||||||
|
|
||||||
|
class RegressionTests(TestCase):
|
||||||
|
|
||||||
|
def test_for_query_result_incomplete_with_inheritance(self):
|
||||||
|
""" https://github.com/bconstantin/django_polymorphic/issues/15 """
|
||||||
|
|
||||||
|
top = Top()
|
||||||
|
top.save()
|
||||||
|
middle = Middle()
|
||||||
|
middle.save()
|
||||||
|
bottom = Bottom()
|
||||||
|
bottom.save()
|
||||||
|
|
||||||
|
expected_queryset = [top, middle, bottom]
|
||||||
|
self.assertQuerysetEqual(Top.objects.all(), [repr(r) for r in expected_queryset])
|
||||||
|
|
||||||
|
expected_queryset = [middle, bottom]
|
||||||
|
self.assertQuerysetEqual(Middle.objects.all(), [repr(r) for r in expected_queryset])
|
||||||
|
|
||||||
|
expected_queryset = [bottom]
|
||||||
|
self.assertQuerysetEqual(Bottom.objects.all(), [repr(r) for r in expected_queryset])
|
||||||
|
|
||||||
|
class MultipleDatabasesTests(TestCase):
|
||||||
|
multi_db = True
|
||||||
|
|
||||||
def test_save_to_non_default_database(self):
|
def test_save_to_non_default_database(self):
|
||||||
Model2A.objects.db_manager('secondary').create(field1='A1')
|
Model2A.objects.db_manager('secondary').create(field1='A1')
|
||||||
Model2C(field1='C1', field2='C2', field3='C3').save(using='secondary')
|
Model2C(field1='C1', field2='C2', field3='C3').save(using='secondary')
|
||||||
|
|
@ -1222,24 +1243,47 @@ class PolymorphicTests(TestCase):
|
||||||
self.assertEqual(repr(objects[0]), '<ModelX: id 2, field_b (CharField), field_x (CharField)>')
|
self.assertEqual(repr(objects[0]), '<ModelX: id 2, field_b (CharField), field_x (CharField)>')
|
||||||
self.assertEqual(repr(objects[1]), '<ModelY: id 3, field_b (CharField), field_y (CharField)>')
|
self.assertEqual(repr(objects[1]), '<ModelY: id 3, field_b (CharField), field_y (CharField)>')
|
||||||
|
|
||||||
class RegressionTests(TestCase):
|
def test_forward_many_to_one_descriptor_on_non_default_database(self):
|
||||||
|
def func():
|
||||||
|
blog = BlogA.objects.db_manager('secondary').create(name='Blog', info='Info')
|
||||||
|
entry = BlogEntry.objects.db_manager('secondary').create(blog=blog, text='Text')
|
||||||
|
ContentType.objects.clear_cache()
|
||||||
|
entry = BlogEntry.objects.db_manager('secondary').get(pk=entry.id)
|
||||||
|
self.assertEqual(blog, entry.blog)
|
||||||
|
|
||||||
def test_for_query_result_incomplete_with_inheritance(self):
|
# Ensure no queries are made using the default database.
|
||||||
""" https://github.com/bconstantin/django_polymorphic/issues/15 """
|
self.assertNumQueries(0, func)
|
||||||
|
|
||||||
top = Top()
|
def test_reverse_many_to_one_descriptor_on_non_default_database(self):
|
||||||
top.save()
|
def func():
|
||||||
middle = Middle()
|
blog = BlogA.objects.db_manager('secondary').create(name='Blog', info='Info')
|
||||||
middle.save()
|
entry = BlogEntry.objects.db_manager('secondary').create(blog=blog, text='Text')
|
||||||
bottom = Bottom()
|
ContentType.objects.clear_cache()
|
||||||
bottom.save()
|
blog = BlogA.objects.db_manager('secondary').get(pk=blog.id)
|
||||||
|
self.assertEqual(entry, blog.blogentry_set.using('secondary').get())
|
||||||
|
|
||||||
expected_queryset = [top, middle, bottom]
|
# Ensure no queries are made using the default database.
|
||||||
self.assertQuerysetEqual(Top.objects.all(), [repr(r) for r in expected_queryset])
|
self.assertNumQueries(0, func)
|
||||||
|
|
||||||
expected_queryset = [middle, bottom]
|
def test_reverse_one_to_one_descriptor_on_non_default_database(self):
|
||||||
self.assertQuerysetEqual(Middle.objects.all(), [repr(r) for r in expected_queryset])
|
def func():
|
||||||
|
m2a = Model2A.objects.db_manager('secondary').create(field1='A1')
|
||||||
|
one2one = One2OneRelatingModel.objects.db_manager('secondary').create(one2one=m2a, field1='121')
|
||||||
|
ContentType.objects.clear_cache()
|
||||||
|
m2a = Model2A.objects.db_manager('secondary').get(pk=m2a.id)
|
||||||
|
self.assertEqual(one2one, m2a.one2onerelatingmodel)
|
||||||
|
|
||||||
expected_queryset = [bottom]
|
# Ensure no queries are made using the default database.
|
||||||
self.assertQuerysetEqual(Bottom.objects.all(), [repr(r) for r in expected_queryset])
|
self.assertNumQueries(0, func)
|
||||||
|
|
||||||
|
def test_many_to_many_descriptor_on_non_default_database(self):
|
||||||
|
def func():
|
||||||
|
m2a = Model2A.objects.db_manager('secondary').create(field1='A1')
|
||||||
|
rm = RelatingModel.objects.db_manager('secondary').create()
|
||||||
|
rm.many2many.add(m2a)
|
||||||
|
ContentType.objects.clear_cache()
|
||||||
|
m2a = Model2A.objects.db_manager('secondary').get(pk=m2a.id)
|
||||||
|
self.assertEqual(rm, m2a.relatingmodel_set.using('secondary').get())
|
||||||
|
|
||||||
|
# Ensure no queries are made using the default database.
|
||||||
|
self.assertNumQueries(0, func)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue