Skip to content

Commit

Permalink
added translate_polymorphic_Q_object
Browse files Browse the repository at this point in the history
  • Loading branch information
bconstantin committed Oct 19, 2010
1 parent 01bdb2f commit c10ff16
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 19 deletions.
1 change: 1 addition & 0 deletions polymorphic/__init__.py
Expand Up @@ -10,6 +10,7 @@
from polymorphic_model import PolymorphicModel
from manager import PolymorphicManager
from query import PolymorphicQuerySet
from query_translate import translate_polymorphic_Q_object
from showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
#from showfields import ShowFieldTypes, ShowFields, ShowFieldsAndTypes # import old names for compatibility

Expand Down
4 changes: 3 additions & 1 deletion polymorphic/query.py
Expand Up @@ -8,14 +8,16 @@
from django.db.models.query import QuerySet
from django.contrib.contenttypes.models import ContentType

from query_translate import translate_polymorphic_filter_definitions_in_kwargs, translate_polymorphic_filter_definitions_in_args, translate_polymorphic_field_path
from query_translate import translate_polymorphic_filter_definitions_in_kwargs, translate_polymorphic_filter_definitions_in_args
from query_translate import translate_polymorphic_field_path

# chunk-size: maximum number of objects requested per db-request
# by the polymorphic queryset.iterator() implementation; we use the same chunk size as Django
from django.db.models.query import CHUNK_SIZE # this is 100 for Django 1.1/1.2
Polymorphic_QuerySet_objects_per_request = CHUNK_SIZE



###################################################################################
### PolymorphicQuerySet

Expand Down
39 changes: 22 additions & 17 deletions polymorphic/query_translate.py
Expand Up @@ -47,6 +47,27 @@ def translate_polymorphic_filter_definitions_in_kwargs(queryset_model, kwargs):

return additional_args

def translate_polymorphic_Q_object(queryset_model, potential_q_object):
def tree_node_correct_field_specs(my_model, node):
" process all children of this Q node "
for i in range(len(node.children)):
child = node.children[i]

if type(child) == tuple:
# this Q object child is a tuple => a kwarg like Q( instance_of=ModelB )
key, val = child
new_expr = _translate_polymorphic_filter_definition(my_model, key, val)
if new_expr:
node.children[i] = new_expr
else:
# this Q object child is another Q object, recursively process this as well
tree_node_correct_field_specs(my_model, child)

if isinstance(potential_q_object, models.Q):
tree_node_correct_field_specs(queryset_model, potential_q_object)

return potential_q_object

def translate_polymorphic_filter_definitions_in_args(queryset_model, args):
"""
Translate the non-keyword argument list for PolymorphicQuerySet.filter()
Expand All @@ -60,24 +81,8 @@ def translate_polymorphic_filter_definitions_in_args(queryset_model, args):
Modifies: args list
"""

def tree_node_correct_field_specs(node):
" process all children of this Q node "
for i in range(len(node.children)):
child = node.children[i]

if type(child) == tuple:
# this Q object child is a tuple => a kwarg like Q( instance_of=ModelB )
key, val = child
new_expr = _translate_polymorphic_filter_definition(queryset_model, key, val)
if new_expr:
node.children[i] = new_expr
else:
# this Q object child is another Q object, recursively process this as well
tree_node_correct_field_specs(child)

for q in args:
if isinstance(q, models.Q):
tree_node_correct_field_specs(q)
translate_polymorphic_Q_object(queryset_model, q)


def _translate_polymorphic_filter_definition(queryset_model, field_path, field_val):
Expand Down
18 changes: 17 additions & 1 deletion polymorphic/tests.py
Expand Up @@ -12,7 +12,9 @@
from django.contrib.contenttypes.models import ContentType
from pprint import pprint

from polymorphic import PolymorphicModel, PolymorphicManager, PolymorphicQuerySet, ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent, get_version
from polymorphic import PolymorphicModel, PolymorphicManager, PolymorphicQuerySet
from polymorphic import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent, get_version
from polymorphic import translate_polymorphic_Q_object

class PlainA(models.Model):
field1 = models.CharField(max_length=10)
Expand Down Expand Up @@ -113,6 +115,10 @@ class BlogEntry(ShowFieldTypeAndContent, PolymorphicModel):
blog = models.ForeignKey(BlogA)
text = models.CharField(max_length=10)

class BlogEntry_limit_choices_to(ShowFieldTypeAndContent, PolymorphicModel):
blog = models.ForeignKey(BlogBase, limit_choices_to=translate_polymorphic_Q_object(BlogBase, Q(instance_of=BlogA) ) )
text = models.CharField(max_length=10)

class ModelFieldNameTest(ShowFieldType, PolymorphicModel):
modelfieldnametest = models.CharField(max_length=10)

Expand All @@ -125,6 +131,7 @@ class InitTestModelSubclass(InitTestModel):
def x(self):
return 'XYZ'


# test bad field name
#class TestBadFieldModel(ShowFieldType, PolymorphicModel):
# instance_of = models.CharField(max_length=10)
Expand Down Expand Up @@ -220,6 +227,15 @@ def test_annotate_aggregate_order(self):

#assert False

def test_limit_choices_to(self):
"this is not really a testcase, as limit_choices_to only affects the Django admin"
# create a blog of type BlogA
blog_a = BlogA.objects.create(name='aa', info='aa')
blog_b = BlogB.objects.create(name='bb')
# create two blog entries
entry1 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2')
entry2 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2')


__test__ = {"doctest": """
#######################################################
Expand Down

0 comments on commit c10ff16

Please sign in to comment.