|
74 | 74 | MultiTableDerived, |
75 | 75 | MyManager, |
76 | 76 | MyManagerQuerySet, |
| 77 | + NonAutoPKChild, |
77 | 78 | NonPolymorphicParent, |
78 | 79 | NonProxyChild, |
79 | 80 | NonSymRelationA, |
80 | 81 | NonSymRelationB, |
81 | 82 | NonSymRelationBase, |
82 | 83 | NonSymRelationBC, |
| 84 | + NonUUIDArtProject, |
83 | 85 | One2OneRelatingModel, |
84 | 86 | One2OneRelatingModelDerived, |
85 | 87 | ParentModel, |
|
112 | 114 | SubclassSelectorProxyBaseModel, |
113 | 115 | SubclassSelectorProxyConcreteModel, |
114 | 116 | ParentLinkAndRelatedName, |
115 | | - TestParentLinkAndRelatedName, |
116 | 117 | UUIDArtProject, |
117 | 118 | UUIDArtProjectA, |
118 | 119 | UUIDArtProjectB, |
@@ -1997,38 +1998,144 @@ def test_infinite_recursion_with_only(self): |
1997 | 1998 | def test_normal_django_to_poly_related_give_poly_type(self): |
1998 | 1999 | obj1 = ParentModel.objects.create(name="m1") |
1999 | 2000 | obj2 = ChildModel.objects.create(name="m2", other_name="m2") |
2000 | | - obj3 = ChildModel.objects.create(name="m1") |
| 2001 | + obj3 = ChildModel.objects.create(name="m3") |
| 2002 | + obj4 = ChildModel.objects.create(name="m3") |
| 2003 | + obj5 = AltChildModel.objects.create(name="m4") |
2001 | 2004 |
|
2002 | 2005 | PlainModel.objects.create(relation=obj1) |
2003 | 2006 | PlainModel.objects.create(relation=obj2) |
2004 | 2007 | PlainModel.objects.create(relation=obj3) |
| 2008 | + PlainModel.objects.create(relation=obj4) |
| 2009 | + PlainModel.objects.create(relation=obj5) |
2005 | 2010 |
|
2006 | | - ContentType.objects.get_for_model(AltChildModel) |
2007 | | - |
2008 | | - with self.assertNumQueries(6): |
| 2011 | + with self.assertNumQueries(10): |
2009 | 2012 | # Queries will be |
2010 | 2013 | # * 1 for All PlainModels object (1) |
2011 | | - # * 1 for each relations ParentModel (4) |
2012 | | - # * 1 for each relations ChilModel is needed (3) |
| 2014 | + # * 1 for each relations ParentModel (5) |
| 2015 | + # * 1 for each relations ChildModel is needed (3) |
| 2016 | + # * 1 for each relations AltChildModel is needed (1) |
2013 | 2017 | multi_q = [ |
2014 | 2018 | # these obj.relation values will have their proper sub type |
2015 | 2019 | obj.relation |
2016 | 2020 | for obj in PlainModel.objects.all() |
2017 | 2021 | ] |
2018 | 2022 | multi_q_types = [type(obj) for obj in multi_q] |
2019 | 2023 |
|
2020 | | - with self.assertNumQueries(2): |
| 2024 | + with self.assertNumQueries(3): |
2021 | 2025 | grouped_q = [ |
2022 | 2026 | # these obj.relation values will all be ParentModel's |
2023 | 2027 | # unless we fix select related but should be their proper |
2024 | 2028 | # sub type by using PolymorphicRelatedQuerySetMixin |
| 2029 | + # 1 query for each relation type |
2025 | 2030 | obj.relation |
2026 | 2031 | for obj in PlainModel.objects.select_related("relation") |
2027 | 2032 | ] |
2028 | 2033 | grouped_q_types = [type(obj) for obj in grouped_q] |
2029 | 2034 |
|
2030 | 2035 | self.assertListEqual(multi_q_types, grouped_q_types) |
2031 | | - self.assertListEqual(grouped_q, [obj1, obj2, obj3]) |
| 2036 | + self.assertListEqual(grouped_q, [obj1, obj2, obj3, obj4, obj5]) |
| 2037 | + |
| 2038 | + def test_normal_django_to_multi_level_poly_related_give_poly_type(self): |
| 2039 | + obj1 = ParentModel.objects.create(name="m1") |
| 2040 | + obj2 = ChildModel.objects.create(name="m2", other_name="c1") |
| 2041 | + obj3 = AltChildModel.objects.create(name="m3") |
| 2042 | + obj4 = AltChildAsBaseModel.objects.create(name="m4", more_name="acab1") |
| 2043 | + |
| 2044 | + PlainModel.objects.create(relation=obj1) |
| 2045 | + PlainModel.objects.create(relation=obj2) |
| 2046 | + PlainModel.objects.create(relation=obj3) |
| 2047 | + PlainModel.objects.create(relation=obj4) |
| 2048 | + |
| 2049 | + with self.assertNumQueries(4): |
| 2050 | + grouped_q = [ |
| 2051 | + # these obj.relation values will all be ParentModel's |
| 2052 | + # unless we fix select related but should be their proper |
| 2053 | + # sub type by using PolymorphicRelatedQuerySetMixin |
| 2054 | + obj.relation |
| 2055 | + for obj in PlainModel.objects.select_related("relation") |
| 2056 | + ] |
| 2057 | + self.assertListEqual(grouped_q, [obj1, obj2, obj3, obj4]) |
| 2058 | + |
| 2059 | + def test_related_fetch_of_different_type_pks(self): |
| 2060 | + "pk on child is not same field type as pk on parent and thus prt field" |
| 2061 | + obj1 = ChildModel.objects.create(name="m1", other_name="c1") |
| 2062 | + obj2 = ParentModel.objects.create(name="m2") |
| 2063 | + obj3 = NonAutoPKChild.objects.create(name="m3", other_name="napk1") |
| 2064 | + obj4 = AltChildModel.objects.create(name="m4", other_name="acm1") |
| 2065 | + obj5 = ChildModel.objects.create(name="m5", other_name="c3") |
| 2066 | + obj6 = AltChildAsBaseModel.objects.create(name="m6", more_name="acab1") |
| 2067 | + obj7 = NonAutoPKChild.objects.create(name="m7", other_name="napk2") |
| 2068 | + |
| 2069 | + PlainModel.objects.create(relation=obj1) |
| 2070 | + PlainModel.objects.create(relation=obj2) |
| 2071 | + PlainModel.objects.create(relation=obj3) |
| 2072 | + PlainModel.objects.create(relation=obj4) |
| 2073 | + PlainModel.objects.create(relation=obj5) |
| 2074 | + PlainModel.objects.create(relation=obj6) |
| 2075 | + PlainModel.objects.create(relation=obj7) |
| 2076 | + |
| 2077 | + def object_info(obj): |
| 2078 | + return { |
| 2079 | + "pk": obj.pk, |
| 2080 | + "parentmodel_ptr": getattr(obj, "parentmodel_ptr_id", None), |
| 2081 | + "altchildmodel_ptr": getattr(obj, "altchildmodel_ptr_id", None), |
| 2082 | + } |
| 2083 | + |
| 2084 | + with self.assertNumQueries(5): |
| 2085 | + grouped_q = [ |
| 2086 | + # these obj.relation values will all be ParentModel's |
| 2087 | + # unless we fix select related but should be their proper |
| 2088 | + # sub type by using PolymorphicRelatedQuerySetMixin |
| 2089 | + obj.relation |
| 2090 | + for obj in PlainModel.objects.select_related("relation").order_by("pk") |
| 2091 | + ] |
| 2092 | + grouped_info = [object_info(obj) for obj in grouped_q] |
| 2093 | + self.assertListEqual( |
| 2094 | + grouped_info, [object_info(obj) for obj in [obj1, obj2, obj3, obj4, obj5, obj6, obj7]] |
| 2095 | + ) |
| 2096 | + self.assertListEqual(grouped_q, [obj1, obj2, obj3, obj4, obj5, obj6, obj7]) |
| 2097 | + |
| 2098 | + def test_related_fetch_of_non_sequential_pks(self): |
| 2099 | + obj1 = ChildModel.objects.create(name="m1", other_name="c1") |
| 2100 | + obj2 = ParentModel.objects.create(name="m2") |
| 2101 | + |
| 2102 | + # FIXME use PK from table to get in sequential PKS |
| 2103 | + # from django.db import connection |
| 2104 | + # with connection.cursor() as cursor: |
| 2105 | + # cursor.execute('INSERT INTO "tests_childmodel" ("other_name", "parentmodel_ptr_id") VALUES (%s, %s)', ['fake', 1]) |
| 2106 | + |
| 2107 | + obj3 = ChildModel.objects.create(name="m3", other_name="c2") |
| 2108 | + obj4 = AltChildModel.objects.create(name="m4", other_name="acm1") |
| 2109 | + obj5 = ChildModel.objects.create(name="m5", other_name="c3") |
| 2110 | + obj6 = AltChildAsBaseModel.objects.create(name="m6", more_name="acab1") |
| 2111 | + |
| 2112 | + PlainModel.objects.create(relation=obj1) |
| 2113 | + PlainModel.objects.create(relation=obj2) |
| 2114 | + PlainModel.objects.create(relation=obj3) |
| 2115 | + PlainModel.objects.create(relation=obj4) |
| 2116 | + PlainModel.objects.create(relation=obj5) |
| 2117 | + PlainModel.objects.create(relation=obj6) |
| 2118 | + |
| 2119 | + def object_info(obj): |
| 2120 | + return { |
| 2121 | + "pk": obj.pk, |
| 2122 | + "parentmodel_ptr": getattr(obj, "parentmodel_ptr_id", None), |
| 2123 | + "altchildmodel_ptr": getattr(obj, "altchildmodel_ptr_id", None), |
| 2124 | + } |
| 2125 | + |
| 2126 | + with self.assertNumQueries(4): |
| 2127 | + grouped_q = [ |
| 2128 | + # these obj.relation values will all be ParentModel's |
| 2129 | + # unless we fix select related but should be their proper |
| 2130 | + # sub type by using PolymorphicRelatedQuerySetMixin |
| 2131 | + obj.relation |
| 2132 | + for obj in PlainModel.objects.select_related("relation") |
| 2133 | + ] |
| 2134 | + grouped_info = [object_info(obj) for obj in grouped_q] |
| 2135 | + self.assertListEqual( |
| 2136 | + grouped_info, [object_info(obj) for obj in [obj1, obj2, obj3, obj4, obj5, obj6]] |
| 2137 | + ) |
| 2138 | + self.assertListEqual(grouped_q, [obj1, obj2, obj3, obj4, obj5, obj6]) |
2032 | 2139 |
|
2033 | 2140 | def test_normal_django_to_poly_related_give_poly_type_using_select_related_true(self): |
2034 | 2141 | obj1 = ParentModel.objects.create(name="m1") |
@@ -2335,7 +2442,12 @@ def test_select_related_fecth_all_poly_classes_indirect_related(self): |
2335 | 2442 |
|
2336 | 2443 | # Prefetch content_types |
2337 | 2444 | ContentType.objects.get_for_models( |
2338 | | - PlainModel, PlainA, ModelExtraExternal, AltChildAsBaseModel, AltChildWithM2MModel |
| 2445 | + AltChildAsBaseModel, |
| 2446 | + AltChildWithM2MModel, |
| 2447 | + ModelExtraExternal, |
| 2448 | + NonAutoPKChild, |
| 2449 | + PlainA, |
| 2450 | + PlainModel, |
2339 | 2451 | ) |
2340 | 2452 |
|
2341 | 2453 | with self.assertNumQueries(1): |
|
0 commit comments