Add support for bulk_create

fix_request_path_info
Krzysztof Gromadzki 2017-12-29 19:05:57 +01:00
parent a2ba52517f
commit 010a23425f
4 changed files with 166 additions and 0 deletions

View File

@ -127,6 +127,12 @@ class PolymorphicQuerySet(QuerySet):
as_manager.queryset_only = True
as_manager = classmethod(as_manager)
def bulk_create(self, objs, batch_size=None):
objs = list(objs)
for obj in objs:
obj.pre_save_polymorphic()
return super(PolymorphicQuerySet, self).bulk_create(objs, batch_size)
def non_polymorphic(self):
"""switch off polymorphic behaviour for this query.
When the queryset is evaluated, only objects of the type of the

View File

@ -1055,4 +1055,82 @@ class Migration(migrations.Migration):
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_tests.inlinemodela_set+', to='contenttypes.ContentType'),
),
migrations.CreateModel(
name='ArtProject',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('topic', models.CharField(max_length=30)),
('artist', models.CharField(max_length=30)),
('polymorphic_ctype',
models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE,
related_name='polymorphic_tests.artproject_set+', to='contenttypes.ContentType')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Duck',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
('weight', models.IntegerField()),
('polymorphic_ctype',
models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE,
related_name='polymorphic_tests.duck_set+', to='contenttypes.ContentType')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MultiTableBase',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('field1', models.CharField(max_length=10)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MultiTableDerived',
fields=[
('multitablebase_ptr',
models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True,
primary_key=True, serialize=False, to='tests.MultiTableBase')),
('field2', models.CharField(max_length=10)),
],
options={
'abstract': False,
},
bases=('tests.multitablebase',),
),
migrations.AddField(
model_name='multitablebase',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE,
related_name='polymorphic_tests.multitablebase_set+',
to='contenttypes.ContentType'),
),
migrations.CreateModel(
name='ReadheadDuck',
fields=[
],
options={
'proxy': True,
'indexes': [],
},
bases=('tests.duck',),
),
migrations.CreateModel(
name='RubberDuck',
fields=[
],
options={
'proxy': True,
'indexes': [],
},
bases=('tests.duck',),
),
]

View File

@ -428,3 +428,39 @@ class InlineModelA(PolymorphicModel):
class InlineModelB(InlineModelA):
field2 = models.CharField(max_length=10)
class AbstractProject(PolymorphicModel):
topic = models.CharField(max_length=30)
class Meta:
abstract = True
class ArtProject(AbstractProject):
artist = models.CharField(max_length=30)
class Duck(PolymorphicModel):
name = models.CharField(max_length=30)
weight = models.IntegerField()
class ReadheadDuck(Duck):
class Meta:
proxy = True
class RubberDuck(Duck):
class Meta:
proxy = True
class MultiTableBase(PolymorphicModel):
field1 = models.CharField(max_length=10)
class MultiTableDerived(MultiTableBase):
field2 = models.CharField(max_length=10)

View File

@ -10,6 +10,7 @@ from django.utils import six
from polymorphic.managers import PolymorphicManager
from polymorphic.models import PolymorphicTypeUndefined
from polymorphic.tests.models import (
ArtProject,
Base,
BlogA,
BlogB,
@ -19,6 +20,7 @@ from polymorphic.tests.models import (
ChildModelWithManager,
CustomPkBase,
CustomPkInherit,
Duck,
Enhance_Base,
Enhance_Inherit,
InitTestModelSubclass,
@ -45,6 +47,7 @@ from polymorphic.tests.models import (
ModelWithMyManagerNoDefault,
ModelX,
ModelY,
MultiTableDerived,
MyManager,
MyManagerQuerySet,
NonProxyChild,
@ -65,10 +68,12 @@ from polymorphic.tests.models import (
ProxyModelB,
ProxyModelBase,
QuerySet,
ReadheadDuck,
RelationA,
RelationB,
RelationBC,
RelationBase,
RubberDuck,
TestParentLinkAndRelatedName,
UUIDArtProject,
UUIDPlainA,
@ -953,6 +958,47 @@ class PolymorphicTests(TransactionTestCase):
with self.assertRaises(PolymorphicTypeUndefined):
list(Model2A.objects.all())
def test_bulk_create_abstract_inheritance(self):
ArtProject.objects.bulk_create([
ArtProject(topic='Painting with Tim', artist='T. Turner'),
ArtProject(topic='Sculpture with Tim', artist='T. Turner'),
])
self.assertEqual(
sorted(ArtProject.objects.values_list('topic', 'artist')),
[('Painting with Tim', 'T. Turner'), ('Sculpture with Tim', 'T. Turner')]
)
def test_bulk_create_proxy_inheritance(self):
ReadheadDuck.objects.bulk_create([
ReadheadDuck(name='readheadduck1', weight=1),
Duck(name='duck1', weight=1),
RubberDuck(name='rubberduck1', weight=1),
])
RubberDuck.objects.bulk_create([
ReadheadDuck(name='readheadduck2', weight=1),
RubberDuck(name='rubberduck2', weight=1),
Duck(name='duck2', weight=1),
])
self.assertEqual(
sorted(ReadheadDuck.objects.values_list('name', flat=True)),
['readheadduck1', 'readheadduck2'],
)
self.assertEqual(
sorted(RubberDuck.objects.values_list('name', flat=True)),
['rubberduck1', 'rubberduck2'],
)
self.assertEqual(
sorted(Duck.objects.values_list('name', flat=True)),
['duck1', 'duck2', 'readheadduck1', 'readheadduck2', 'rubberduck1', 'rubberduck2'],
)
def test_bulk_create_unsupported_multi_table_inheritance(self):
expected_message = 'Can\'t bulk create a multi-table inherited model'
with self.assertRaisesMessage(ValueError, expected_message):
MultiTableDerived.objects.bulk_create([
MultiTableDerived(field1='field1', field2='field2')
])
def qrepr(data):
"""