added translate_polymorphic_Q_object
parent
01bdb2f9b0
commit
c10ff1650b
|
|
@ -10,6 +10,7 @@ Please see LICENSE and AUTHORS for more information.
|
||||||
from polymorphic_model import PolymorphicModel
|
from polymorphic_model import PolymorphicModel
|
||||||
from manager import PolymorphicManager
|
from manager import PolymorphicManager
|
||||||
from query import PolymorphicQuerySet
|
from query import PolymorphicQuerySet
|
||||||
|
from query_translate import translate_polymorphic_Q_object
|
||||||
from showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
|
from showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
|
||||||
#from showfields import ShowFieldTypes, ShowFields, ShowFieldsAndTypes # import old names for compatibility
|
#from showfields import ShowFieldTypes, ShowFields, ShowFieldsAndTypes # import old names for compatibility
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ from compatibility_tools import defaultdict
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.contrib.contenttypes.models import ContentType
|
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
|
# chunk-size: maximum number of objects requested per db-request
|
||||||
# by the polymorphic queryset.iterator() implementation; we use the same chunk size as Django
|
# by the polymorphic queryset.iterator() implementation; we use the same chunk size as Django
|
||||||
|
|
@ -16,6 +17,7 @@ from django.db.models.query import CHUNK_SIZE # this is 100 for Dj
|
||||||
Polymorphic_QuerySet_objects_per_request = CHUNK_SIZE
|
Polymorphic_QuerySet_objects_per_request = CHUNK_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
### PolymorphicQuerySet
|
### PolymorphicQuerySet
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,27 @@ def translate_polymorphic_filter_definitions_in_kwargs(queryset_model, kwargs):
|
||||||
|
|
||||||
return additional_args
|
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):
|
def translate_polymorphic_filter_definitions_in_args(queryset_model, args):
|
||||||
"""
|
"""
|
||||||
Translate the non-keyword argument list for PolymorphicQuerySet.filter()
|
Translate the non-keyword argument list for PolymorphicQuerySet.filter()
|
||||||
|
|
@ -60,24 +81,8 @@ def translate_polymorphic_filter_definitions_in_args(queryset_model, args):
|
||||||
Modifies: args list
|
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:
|
for q in args:
|
||||||
if isinstance(q, models.Q):
|
translate_polymorphic_Q_object(queryset_model, q)
|
||||||
tree_node_correct_field_specs(q)
|
|
||||||
|
|
||||||
|
|
||||||
def _translate_polymorphic_filter_definition(queryset_model, field_path, field_val):
|
def _translate_polymorphic_filter_definition(queryset_model, field_path, field_val):
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,9 @@ from django.db import models
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from pprint import pprint
|
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):
|
class PlainA(models.Model):
|
||||||
field1 = models.CharField(max_length=10)
|
field1 = models.CharField(max_length=10)
|
||||||
|
|
@ -113,6 +115,10 @@ class BlogEntry(ShowFieldTypeAndContent, PolymorphicModel):
|
||||||
blog = models.ForeignKey(BlogA)
|
blog = models.ForeignKey(BlogA)
|
||||||
text = models.CharField(max_length=10)
|
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):
|
class ModelFieldNameTest(ShowFieldType, PolymorphicModel):
|
||||||
modelfieldnametest = models.CharField(max_length=10)
|
modelfieldnametest = models.CharField(max_length=10)
|
||||||
|
|
||||||
|
|
@ -125,6 +131,7 @@ class InitTestModelSubclass(InitTestModel):
|
||||||
def x(self):
|
def x(self):
|
||||||
return 'XYZ'
|
return 'XYZ'
|
||||||
|
|
||||||
|
|
||||||
# test bad field name
|
# test bad field name
|
||||||
#class TestBadFieldModel(ShowFieldType, PolymorphicModel):
|
#class TestBadFieldModel(ShowFieldType, PolymorphicModel):
|
||||||
# instance_of = models.CharField(max_length=10)
|
# instance_of = models.CharField(max_length=10)
|
||||||
|
|
@ -220,6 +227,15 @@ class testclass(TestCase):
|
||||||
|
|
||||||
#assert False
|
#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": """
|
__test__ = {"doctest": """
|
||||||
#######################################################
|
#######################################################
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue