added "queryset.get_real_instances()" usage, added testcase
parent
8c3df56cb6
commit
6befe6c733
29
DOCS.rst
29
DOCS.rst
|
|
@ -235,15 +235,21 @@ existing polymorphic inheritance tree::
|
||||||
Non-Polymorphic Queries
|
Non-Polymorphic Queries
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
>>> ModelA.objects.all().non_polymorphic()
|
If you insert ``.non_polymorphic()`` anywhere into the query chain, then
|
||||||
.
|
django_polymorphic will simply leave out the final step of retrieving the
|
||||||
[ <ModelA: id 1, field1 (CharField)>,
|
real objects, and the manager/queryset will return objects of the type of
|
||||||
<ModelA: id 2, field1 (CharField)>,
|
the base class you used for the query, like vanilla Django would
|
||||||
<ModelA: id 3, field1 (CharField)> ]
|
(``ModelA`` in this example).
|
||||||
|
|
||||||
|
There are no other changes in the behaviour of the queryset. For example,
|
||||||
|
enhancements for ``filter()`` or ``instance_of()`` etc. still work as expected.
|
||||||
|
If you do the final step yourself, you get the usual polymorphic result:
|
||||||
|
|
||||||
|
>>> qs.get_real_instances()
|
||||||
|
[ <ModelA: id 1, field1 (CharField)>,
|
||||||
|
<ModelB: id 2, field1 (CharField), field2 (CharField)>,
|
||||||
|
<ModelC: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ]
|
||||||
|
|
||||||
Except for the return of the of the base class objects, there are no
|
|
||||||
changes in the behaviour of the queryset (i.e. the enhancements
|
|
||||||
for ``filter()`` or ``instance_of()`` etc. still work as expected).
|
|
||||||
|
|
||||||
About Queryset Methods
|
About Queryset Methods
|
||||||
----------------------
|
----------------------
|
||||||
|
|
@ -268,10 +274,11 @@ About Queryset Methods
|
||||||
(this case could be made to work, however it may be mostly unneeded)..
|
(this case could be made to work, however it may be mostly unneeded)..
|
||||||
The keyword-argument "polymorphic" is no longer supported.
|
The keyword-argument "polymorphic" is no longer supported.
|
||||||
|
|
||||||
+ ``get_real_instances(base_objects_list_or_queryset)`` allows you to turn a
|
+ ``get_real_instances()`` allows you to turn a
|
||||||
queryset or list of base model objects efficiently into the real objects.
|
queryset or list of base model objects efficiently into the real objects.
|
||||||
For example, you could do ``base_objects=ModelA.extra(...).non_polymorphic()``
|
For example, you could do ``base_objects_queryset=ModelA.extra(...).non_polymorphic()``
|
||||||
and then call ``real_objects=ModelA.objects.get_real_instances(base_objects)``.
|
and then call ``real_objects=base_objects_queryset.get_real_instances()``.Or alternatively
|
||||||
|
.``real_objects=ModelA.objects..get_real_instances(base_objects_queryset_or_object_list)``
|
||||||
|
|
||||||
* ``values()`` & ``values_list()`` currently do not return polymorphic
|
* ``values()`` & ``values_list()`` currently do not return polymorphic
|
||||||
results. This may change in the future however. If you want to use these
|
results. This may change in the future however. If you want to use these
|
||||||
|
|
|
||||||
|
|
@ -91,13 +91,14 @@ class PolymorphicQuerySet(QuerySet):
|
||||||
self.polymorphic_disabled = True
|
self.polymorphic_disabled = True
|
||||||
return super(PolymorphicQuerySet, self).aggregate(*args, **kwargs)
|
return super(PolymorphicQuerySet, self).aggregate(*args, **kwargs)
|
||||||
|
|
||||||
# Since django_polymorphic 'V1.0 beta2', extra() always returns polymorphic results.
|
# Since django_polymorphic 'V1.0 beta2', extra() always returns polymorphic results.^
|
||||||
# The resulting objects are required to have a unique primary key within the result set
|
# The resulting objects are required to have a unique primary key within the result set
|
||||||
# (otherwise an error is thrown).
|
# (otherwise an error is thrown).
|
||||||
# The "polymorphic" keyword argument is not supported anymore.
|
# The "polymorphic" keyword argument is not supported anymore.
|
||||||
#def extra(self, *args, **kwargs):
|
#def extra(self, *args, **kwargs):
|
||||||
|
|
||||||
def get_real_instances(self, base_result_objects):
|
|
||||||
|
def _get_real_instances(self, base_result_objects):
|
||||||
"""
|
"""
|
||||||
Polymorphic object loader
|
Polymorphic object loader
|
||||||
|
|
||||||
|
|
@ -229,7 +230,7 @@ class PolymorphicQuerySet(QuerySet):
|
||||||
reached_end = True
|
reached_end = True
|
||||||
break
|
break
|
||||||
|
|
||||||
real_results = self.get_real_instances(base_result_objects)
|
real_results = self._get_real_instances(base_result_objects)
|
||||||
|
|
||||||
for o in real_results:
|
for o in real_results:
|
||||||
yield o
|
yield o
|
||||||
|
|
@ -243,3 +244,17 @@ class PolymorphicQuerySet(QuerySet):
|
||||||
else:
|
else:
|
||||||
return super(PolymorphicQuerySet,self).__repr__(*args, **kwargs)
|
return super(PolymorphicQuerySet,self).__repr__(*args, **kwargs)
|
||||||
|
|
||||||
|
class _p_list_class(list):
|
||||||
|
def __repr__(self, *args, **kwargs):
|
||||||
|
result = [ repr(o) for o in self ]
|
||||||
|
return '[ ' + ',\n '.join(result) + ' ]'
|
||||||
|
|
||||||
|
def get_real_instances(self, base_result_objects=None):
|
||||||
|
"same as _get_real_instances, but make sure that __repr__ for ShowField... creates correct output"
|
||||||
|
if not base_result_objects: base_result_objects=self
|
||||||
|
olist = self._get_real_instances(base_result_objects)
|
||||||
|
if not self.model.polymorphic_query_multiline_output:
|
||||||
|
return olist
|
||||||
|
clist=PolymorphicQuerySet._p_list_class(olist)
|
||||||
|
return clist
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ __test__ = {"doctest": """
|
||||||
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
|
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
|
||||||
|
|
||||||
# manual get_real_instance()
|
# manual get_real_instance()
|
||||||
>>> o=Model2A.base_objects.get(field1='C1')
|
>>> o=Model2A.objects.non_polymorphic().get(field1='C1')
|
||||||
>>> o.get_real_instance()
|
>>> o.get_real_instance()
|
||||||
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>
|
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>
|
||||||
|
|
||||||
|
|
@ -296,6 +296,20 @@ __test__ = {"doctest": """
|
||||||
<Model2A: id 3, field1 (CharField)>,
|
<Model2A: id 3, field1 (CharField)>,
|
||||||
<Model2A: id 4, field1 (CharField)> ]
|
<Model2A: id 4, field1 (CharField)> ]
|
||||||
|
|
||||||
|
# get_real_instances()
|
||||||
|
>>> qs.get_real_instances()
|
||||||
|
[ <Model2A: id 1, field1 (CharField)>,
|
||||||
|
<Model2B: id 2, field1 (CharField), field2 (CharField)>,
|
||||||
|
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
|
||||||
|
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
|
||||||
|
|
||||||
|
>>> l=list(qs)
|
||||||
|
>>> Model2A.objects.get_real_instances(l)
|
||||||
|
[ <Model2A: id 1, field1 (CharField)>,
|
||||||
|
<Model2B: id 2, field1 (CharField), field2 (CharField)>,
|
||||||
|
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
|
||||||
|
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
|
||||||
|
|
||||||
|
|
||||||
### test inheritance pointers & _base_managers
|
### test inheritance pointers & _base_managers
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue