Skip to content

Commit 2d6f9f0

Browse files
mjnaderibckohan
andcommitted
- Add a failing test to demonstrate a bug
- regenerate migrations, fix test - remove prints - move test to regressions Co-authored-by: Mohammad Javad Naderi <mjnaderi@gmail.com> Co-authored-by: Brian Kohan <bckohan@gmail.com>
1 parent 9399f7d commit 2d6f9f0

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

src/polymorphic/tests/migrations/0001_initial.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 4.2.26 on 2025-12-01 11:40
1+
# Generated by Django 4.2.26 on 2025-12-02 16:47
22

33
from django.db import migrations, models
44
import django.db.models.deletion
@@ -197,6 +197,17 @@ class Migration(migrations.Migration):
197197
'base_manager_name': 'objects',
198198
},
199199
),
200+
migrations.CreateModel(
201+
name='Participant',
202+
fields=[
203+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
204+
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype')),
205+
],
206+
options={
207+
'abstract': False,
208+
'base_manager_name': 'objects',
209+
},
210+
),
200211
migrations.CreateModel(
201212
name='PlainA',
202213
fields=[
@@ -591,6 +602,18 @@ class Migration(migrations.Migration):
591602
},
592603
bases=('tests.modelshow1_plain',),
593604
),
605+
migrations.CreateModel(
606+
name='UserProfile',
607+
fields=[
608+
('participant_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tests.participant')),
609+
('name', models.CharField(max_length=100)),
610+
],
611+
options={
612+
'abstract': False,
613+
'base_manager_name': 'objects',
614+
},
615+
bases=('tests.participant',),
616+
),
594617
migrations.CreateModel(
595618
name='UUIDArtProject',
596619
fields=[
@@ -1050,6 +1073,14 @@ class Migration(migrations.Migration):
10501073
],
10511074
bases=('tests.uuidplainb',),
10521075
),
1076+
migrations.CreateModel(
1077+
name='Team',
1078+
fields=[
1079+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
1080+
('team_name', models.CharField(max_length=100)),
1081+
('user_profiles', models.ManyToManyField(related_name='user_teams', to='tests.userprofile')),
1082+
],
1083+
),
10531084
migrations.CreateModel(
10541085
name='InlineModelB',
10551086
fields=[

src/polymorphic/tests/models.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,19 @@ class SubclassSelectorProxyConcreteModel(SubclassSelectorProxyModel):
519519

520520
class NonPolymorphicParent(PolymorphicModel, Group):
521521
test = models.CharField(max_length=30, default="test_non_polymorphic_parent")
522+
523+
524+
class Participant(PolymorphicModel):
525+
pass
526+
527+
528+
class UserProfile(Participant):
529+
name = models.CharField(max_length=100)
530+
531+
def __str__(self):
532+
return self.name
533+
534+
535+
class Team(models.Model):
536+
team_name = models.CharField(max_length=100)
537+
user_profiles = models.ManyToManyField(UserProfile, related_name="user_teams")

src/polymorphic/tests/test_regression.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.test import TestCase
22

3-
from polymorphic.tests.models import Bottom, Middle, Top
3+
from polymorphic.tests.models import Bottom, Middle, Top, Team, UserProfile
44

55

66
class RegressionTests(TestCase):
@@ -34,3 +34,41 @@ def test_for_query_result_incomplete_with_inheritance(self):
3434
[repr(r) for r in expected_queryset],
3535
transform=repr,
3636
)
37+
38+
def test_pr_254(self):
39+
user_a = UserProfile.objects.create(name="a")
40+
user_b = UserProfile.objects.create(name="b")
41+
user_c = UserProfile.objects.create(name="c")
42+
43+
team1 = Team.objects.create(team_name="team1")
44+
team1.user_profiles.add(user_a, user_b, user_c)
45+
team1.save()
46+
47+
team2 = Team.objects.create(team_name="team2")
48+
team2.user_profiles.add(user_c)
49+
team2.save()
50+
51+
# without prefetch_related, the test passes
52+
my_teams = (
53+
Team.objects.filter(user_profiles=user_c)
54+
.order_by("team_name")
55+
.prefetch_related("user_profiles")
56+
.distinct()
57+
)
58+
59+
self.assertEqual(len(my_teams[0].user_profiles.all()), 3)
60+
61+
self.assertEqual(len(my_teams[1].user_profiles.all()), 1)
62+
63+
self.assertEqual(len(my_teams[0].user_profiles.all()), 3)
64+
self.assertEqual(len(my_teams[1].user_profiles.all()), 1)
65+
66+
# without this "for" loop, the test passes
67+
for _ in my_teams:
68+
pass
69+
70+
# This time, test fails. PR 254 claim
71+
# with sqlite: 4 != 3
72+
# with postgresql: 2 != 3
73+
self.assertEqual(len(my_teams[0].user_profiles.all()), 3)
74+
self.assertEqual(len(my_teams[1].user_profiles.all()), 1)

0 commit comments

Comments
 (0)