Merge pull request #365 from ghost/fix/37-subclass-selector-on-abstract-proxy-models

#37: Fix model subclass ___ selector for abstract/proxy models
fix_request_path_info
Diederik van der Boor 2019-07-11 22:12:24 +02:00 committed by GitHub
commit ec3fb34f08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 121 additions and 6 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@ build/
dist/
docs/_build/
htmlcov/
venv/

View File

@ -196,6 +196,8 @@ def translate_polymorphic_field_path(queryset_model, field_path):
return myclass.__name__.lower()
path = _create_base_path(baseclass, b)
if path:
if b._meta.abstract or b._meta.proxy:
return myclass.__name__.lower()
return path + '__' + myclass.__name__.lower()
return ''

View File

@ -1130,4 +1130,66 @@ class Migration(migrations.Migration):
},
bases=('tests.duck',),
),
migrations.CreateModel(
name='SubclassSelectorAbstractBaseModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('base_field', models.CharField(default='test_bf', max_length=10)),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
),
migrations.CreateModel(
name='SubclassSelectorProxyBaseModel',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('base_field', models.CharField(default='test_bf', max_length=10)),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_tests.subclassselectorproxybasemodel_set+', to='contenttypes.ContentType')),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
),
migrations.CreateModel(
name='SubclassSelectorAbstractConcreteModel',
fields=[
('subclassselectorabstractbasemodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tests.SubclassSelectorAbstractBaseModel')),
('abstract_field', models.CharField(default='test_af', max_length=10)),
('concrete_field', models.CharField(default='test_cf', max_length=10)),
],
options={
'abstract': False,
},
bases=('tests.subclassselectorabstractbasemodel',),
),
migrations.AddField(
model_name='subclassselectorabstractbasemodel',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_tests.subclassselectorabstractbasemodel_set+', to='contenttypes.ContentType'),
),
migrations.CreateModel(
name='SubclassSelectorProxyModel',
fields=[
],
options={
'proxy': True,
'indexes': [],
},
bases=('tests.subclassselectorproxybasemodel',),
),
migrations.CreateModel(
name='SubclassSelectorProxyConcreteModel',
fields=[
('subclassselectorproxybasemodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='tests.SubclassSelectorProxyBaseModel')),
('concrete_field', models.CharField(default='test_cf', max_length=10)),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
bases=('tests.subclassselectorproxymodel',),
),
]

View File

@ -450,3 +450,31 @@ class MultiTableBase(PolymorphicModel):
class MultiTableDerived(MultiTableBase):
field2 = models.CharField(max_length=10)
class SubclassSelectorAbstractBaseModel(PolymorphicModel):
base_field = models.CharField(max_length=10, default='test_bf')
class SubclassSelectorAbstractModel(SubclassSelectorAbstractBaseModel):
abstract_field = models.CharField(max_length=10, default='test_af')
class Meta:
abstract = True
class SubclassSelectorAbstractConcreteModel(SubclassSelectorAbstractModel):
concrete_field = models.CharField(max_length=10, default='test_cf')
class SubclassSelectorProxyBaseModel(PolymorphicModel):
base_field = models.CharField(max_length=10, default='test_bf')
class SubclassSelectorProxyModel(SubclassSelectorProxyBaseModel):
class Meta:
proxy = True
class SubclassSelectorProxyConcreteModel(SubclassSelectorProxyModel):
concrete_field = models.CharField(max_length=10, default='test_cf')

View File

@ -74,6 +74,10 @@ from polymorphic.tests.models import (
RelationBC,
RelationBase,
RubberDuck,
SubclassSelectorAbstractBaseModel,
SubclassSelectorAbstractConcreteModel,
SubclassSelectorProxyBaseModel,
SubclassSelectorProxyConcreteModel,
TestParentLinkAndRelatedName,
UUIDArtProject,
UUIDPlainA,
@ -859,21 +863,21 @@ class PolymorphicTests(TransactionTestCase):
self.assertEqual(ProxyModelB.objects.model, ProxyModelB)
# Create objects
ProxyModelA.objects.create(name="object1")
ProxyModelB.objects.create(name="object2", field2="bb")
object1_pk = ProxyModelA.objects.create(name="object1").pk
object2_pk = ProxyModelB.objects.create(name="object2", field2="bb").pk
# Getting single objects
object1 = ProxyModelBase.objects.get(name='object1')
object2 = ProxyModelBase.objects.get(name='object2')
self.assertEqual(repr(object1), '<ProxyModelA: id 1, name (CharField) "object1", field1 (CharField) "">')
self.assertEqual(repr(object2), '<ProxyModelB: id 2, name (CharField) "object2", field2 (CharField) "bb">')
self.assertEqual(repr(object1), '<ProxyModelA: id %i, name (CharField) "object1", field1 (CharField) "">' % object1_pk)
self.assertEqual(repr(object2), '<ProxyModelB: id %i, name (CharField) "object2", field2 (CharField) "bb">' % object2_pk)
self.assertIsInstance(object1, ProxyModelA)
self.assertIsInstance(object2, ProxyModelB)
# Same for lists
objects = list(ProxyModelBase.objects.all().order_by('name'))
self.assertEqual(repr(objects[0]), '<ProxyModelA: id 1, name (CharField) "object1", field1 (CharField) "">')
self.assertEqual(repr(objects[1]), '<ProxyModelB: id 2, name (CharField) "object2", field2 (CharField) "bb">')
self.assertEqual(repr(objects[0]), '<ProxyModelA: id %i, name (CharField) "object1", field1 (CharField) "">' % object1_pk)
self.assertEqual(repr(objects[1]), '<ProxyModelB: id %i, name (CharField) "object2", field2 (CharField) "bb">' % object2_pk)
self.assertIsInstance(objects[0], ProxyModelA)
self.assertIsInstance(objects[1], ProxyModelB)
@ -1024,3 +1028,21 @@ class PolymorphicTests(TransactionTestCase):
MultiTableDerived.objects.bulk_create([
MultiTableDerived(field1='field1', field2='field2')
])
def test_can_query_using_subclass_selector_on_abstract_model(self):
obj = SubclassSelectorAbstractConcreteModel.objects.create(concrete_field='abc')
queried_obj = SubclassSelectorAbstractBaseModel.objects.filter(
SubclassSelectorAbstractConcreteModel___concrete_field='abc'
).get()
self.assertEqual(obj.pk, queried_obj.pk)
def test_can_query_using_subclass_selector_on_proxy_model(self):
obj = SubclassSelectorProxyConcreteModel.objects.create(concrete_field='abc')
queried_obj = SubclassSelectorProxyBaseModel.objects.filter(
SubclassSelectorProxyConcreteModel___concrete_field='abc'
).get()
self.assertEqual(obj.pk, queried_obj.pk)