Skip to content

Commit 59cfde0

Browse files
bdabrowskibckohan
authored andcommitted
- Fixed bug in checking the existence of custom __init__ method in an object. The __init__ wasn't called previously.
- Added unit-tests for #615
1 parent 347ef6d commit 59cfde0

File tree

4 files changed

+69
-16
lines changed

4 files changed

+69
-16
lines changed

src/polymorphic/query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def transmogrify(cls, obj):
8787
"""
8888
Upcast a class to a different type without asking questions.
8989
"""
90-
if "__init__" not in obj.__dict__:
90+
if "__init__" not in obj.__class__.__dict__:
9191
# Just assign __class__ to a different value.
9292
new = obj
9393
new.__class__ = cls

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

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Generated by Django 4.2.26 on 2025-12-02 16:47
1+
# Generated by Django 4.2.26 on 2025-12-03 23:29
22

33
from django.db import migrations, models
44
import django.db.models.deletion
@@ -12,8 +12,8 @@ class Migration(migrations.Migration):
1212
initial = True
1313

1414
dependencies = [
15-
('auth', '0012_alter_user_first_name_max_length'),
1615
('contenttypes', '0002_remove_content_type_name'),
16+
('auth', '0012_alter_user_first_name_max_length'),
1717
]
1818

1919
operations = [
@@ -56,6 +56,18 @@ class Migration(migrations.Migration):
5656
},
5757
bases=(polymorphic.showfields.ShowFieldTypeAndContent, models.Model),
5858
),
59+
migrations.CreateModel(
60+
name='Duck',
61+
fields=[
62+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
63+
('name', models.CharField(max_length=30)),
64+
('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')),
65+
],
66+
options={
67+
'abstract': False,
68+
'base_manager_name': 'objects',
69+
},
70+
),
5971
migrations.CreateModel(
6072
name='Enhance_Base',
6173
fields=[
@@ -315,6 +327,17 @@ class Migration(migrations.Migration):
315327
},
316328
bases=('tests.blogbase',),
317329
),
330+
migrations.CreateModel(
331+
name='BlueHeadDuck',
332+
fields=[
333+
('duck_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tests.duck')),
334+
],
335+
options={
336+
'abstract': False,
337+
'base_manager_name': 'objects',
338+
},
339+
bases=('tests.duck',),
340+
),
318341
migrations.CreateModel(
319342
name='CustomPkInherit',
320343
fields=[
@@ -833,18 +856,6 @@ class Migration(migrations.Migration):
833856
'base_manager_name': 'objects',
834857
},
835858
),
836-
migrations.CreateModel(
837-
name='Duck',
838-
fields=[
839-
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
840-
('name', models.CharField(max_length=30)),
841-
('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')),
842-
],
843-
options={
844-
'abstract': False,
845-
'base_manager_name': 'objects',
846-
},
847-
),
848859
migrations.CreateModel(
849860
name='DateModel',
850861
fields=[
@@ -1108,6 +1119,17 @@ class Migration(migrations.Migration):
11081119
},
11091120
bases=(polymorphic.showfields.ShowFieldTypeAndContent, models.Model),
11101121
),
1122+
migrations.CreateModel(
1123+
name='PurpleHeadDuck',
1124+
fields=[
1125+
],
1126+
options={
1127+
'proxy': True,
1128+
'indexes': [],
1129+
'constraints': [],
1130+
},
1131+
bases=('tests.blueheadduck', models.Model),
1132+
),
11111133
migrations.CreateModel(
11121134
name='Model2D',
11131135
fields=[

src/polymorphic/tests/models.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,3 +535,23 @@ def __str__(self):
535535
class Team(models.Model):
536536
team_name = models.CharField(max_length=100)
537537
user_profiles = models.ManyToManyField(UserProfile, related_name="user_teams")
538+
539+
540+
class BlueHeadDuck(Duck):
541+
def __init__(self, *args, **kwargs):
542+
super().__init__(*args, **kwargs)
543+
self.color = "blue"
544+
545+
546+
class HomeDuck(models.Model):
547+
def __init__(self, *args, **kwargs):
548+
super().__init__(*args, **kwargs)
549+
self.home = "Duckburg"
550+
551+
class Meta:
552+
abstract = True
553+
554+
555+
class PurpleHeadDuck(HomeDuck, BlueHeadDuck):
556+
class Meta:
557+
proxy = True

src/polymorphic/tests/test_orm.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
ChildModelWithManager,
2424
CustomPkBase,
2525
CustomPkInherit,
26-
Duck,
2726
Enhance_Base,
2827
Enhance_Inherit,
2928
InitTestModelSubclass,
@@ -90,6 +89,8 @@
9089
UUIDPlainC,
9190
UUIDProject,
9291
UUIDResearchProject,
92+
Duck,
93+
PurpleHeadDuck,
9394
)
9495

9596

@@ -1411,3 +1412,13 @@ def test_iteration(self):
14111412
# known deletion issue with oracle
14121413
# https://github.com/jazzband/django-polymorphic/issues/673
14131414
pass
1415+
1416+
def test_transmogrify_with_init(self):
1417+
pur = PurpleHeadDuck.objects.create()
1418+
assert pur.color == "blue"
1419+
assert pur.home == "Duckburg"
1420+
1421+
pur = Duck.objects.get(id=pur.id)
1422+
assert pur.color == "blue"
1423+
# issues/615 fixes following line:
1424+
assert pur.home == "Duckburg"

0 commit comments

Comments
 (0)