added "queryset.get_real_instances()" usage, added testcase

fix_request_path_info
Bert Constantin 2010-10-25 09:28:08 +02:00
parent 8c3df56cb6
commit 6befe6c733
3 changed files with 52 additions and 16 deletions

View File

@ -235,16 +235,22 @@ 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

View File

@ -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

View File

@ -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