Skip to content

Commit 5e18bb1

Browse files
committed
more polymorphic-related tests
1 parent 6968780 commit 5e18bb1

File tree

2 files changed

+226
-1
lines changed

2 files changed

+226
-1
lines changed

polymorphic_tree/tests/test_models.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from django.db.models import Q
55
from django.test import TestCase
66

7-
from polymorphic import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
7+
from .utils import ShowFieldType
88

99
from polymorphic_tree.models import PolymorphicMPTTModel, PolymorphicTreeForeignKey
1010

@@ -42,9 +42,44 @@ class One2OneRelatingModelDerived(One2OneRelatingModel):
4242
field2 = models.CharField(max_length=10)
4343

4444

45+
class Base(ShowFieldType, PolymorphicMPTTModel):
46+
parent = PolymorphicTreeForeignKey('self', blank=True, null=True, related_name='children', verbose_name='parent')
47+
field_b = models.CharField(max_length=10)
48+
49+
class ModelX(Base):
50+
field_x = models.CharField(max_length=10)
51+
52+
class ModelY(Base):
53+
field_y = models.CharField(max_length=10)
54+
55+
4556
class PolymorphicTreeTests(TestCase):
4657
"""
4758
Test Suite, largely derived from django-polymorphic tests
59+
60+
TODO: potentially port these tests from django_polymorphic.tests
61+
62+
test_foreignkey_field()
63+
test_onetoone_field()
64+
test_manytomany_field()
65+
test_extra_method()
66+
test_instance_of_filter()
67+
test_polymorphic___filter()
68+
test_delete()
69+
test_combine_querysets()
70+
test_multiple_inheritance()
71+
test_relation_base()
72+
test_user_defined_manager()
73+
test_manager_inheritance()
74+
test_queryset_assignment()
75+
test_proxy_models()
76+
test_proxy_get_real_instance_class()
77+
test_content_types_for_proxy_models()
78+
test_proxy_model_inheritance()
79+
test_custom_pk()
80+
test_fix_getattribute()
81+
test_parent_link_and_related_name()
82+
4883
"""
4984

5085
def create_model2abcd(self):
@@ -124,3 +159,26 @@ def show_base_manager(model):
124159

125160
self.assertEqual(show_base_manager(One2OneRelatingModel), "<class 'polymorphic_tree.managers.PolymorphicMPTTModelManager'> <class 'polymorphic_tree.tests.test_models.One2OneRelatingModel'>")
126161
self.assertEqual(show_base_manager(One2OneRelatingModelDerived), "<class 'django.db.models.manager.Manager'> <class 'polymorphic_tree.tests.test_models.One2OneRelatingModelDerived'>")
162+
163+
def test_instance_default_manager(self):
164+
def show_default_manager(instance):
165+
return "{0} {1}".format(
166+
repr(type(instance._default_manager)),
167+
repr(instance._default_manager.model)
168+
)
169+
170+
plain_a = PlainA(field1='C1')
171+
plain_b = PlainB(field2='C1')
172+
plain_c = PlainC(field3='C1')
173+
174+
model_2a = Model2A(field1='C1')
175+
model_2b = Model2B(field2='C1')
176+
model_2c = Model2C(field3='C1')
177+
178+
self.assertEqual(show_default_manager(plain_a), "<class 'django.db.models.manager.Manager'> <class 'polymorphic_tree.tests.test_models.PlainA'>")
179+
self.assertEqual(show_default_manager(plain_b), "<class 'django.db.models.manager.Manager'> <class 'polymorphic_tree.tests.test_models.PlainB'>")
180+
self.assertEqual(show_default_manager(plain_c), "<class 'django.db.models.manager.Manager'> <class 'polymorphic_tree.tests.test_models.PlainC'>")
181+
182+
self.assertEqual(show_default_manager(model_2a), "<class 'polymorphic_tree.managers.PolymorphicMPTTModelManager'> <class 'polymorphic_tree.tests.test_models.Model2A'>")
183+
self.assertEqual(show_default_manager(model_2b), "<class 'polymorphic_tree.managers.PolymorphicMPTTModelManager'> <class 'polymorphic_tree.tests.test_models.Model2B'>")
184+
self.assertEqual(show_default_manager(model_2c), "<class 'polymorphic_tree.managers.PolymorphicMPTTModelManager'> <class 'polymorphic_tree.tests.test_models.Model2C'>")

polymorphic_tree/tests/utils.py

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# -*- coding: utf-8 -*-
2+
""" from https://github.com/chrisglass/django_polymorphic/blob/master/polymorphic/showfields.py
3+
"""
4+
5+
from django.db import models
6+
from django.utils import six
7+
8+
9+
class ShowFieldBase(object):
10+
""" base class for the ShowField... model mixins, does the work """
11+
12+
polymorphic_query_multiline_output = True # cause nicer multiline PolymorphicQuery output
13+
14+
polymorphic_showfield_type = False
15+
polymorphic_showfield_content = False
16+
17+
# these may be overridden by the user
18+
polymorphic_showfield_max_line_width = None
19+
polymorphic_showfield_max_field_width = 20
20+
polymorphic_showfield_old_format = False
21+
22+
def __repr__(self):
23+
return self.__unicode__()
24+
25+
def _showfields_get_content(self, field_name, field_type=type(None)):
26+
"helper for __unicode__"
27+
content = getattr(self, field_name)
28+
if self.polymorphic_showfield_old_format:
29+
out = ': '
30+
else:
31+
out = ' '
32+
if issubclass(field_type, models.ForeignKey):
33+
if content is None:
34+
out += 'None'
35+
else:
36+
out += content.__class__.__name__
37+
elif issubclass(field_type, models.ManyToManyField):
38+
out += '%d' % content.count()
39+
elif isinstance(content, six.integer_types):
40+
out += str(content)
41+
elif content is None:
42+
out += 'None'
43+
else:
44+
txt = str(content)
45+
if len(txt) > self.polymorphic_showfield_max_field_width:
46+
txt = txt[:self.polymorphic_showfield_max_field_width - 2] + '..'
47+
out += '"' + txt + '"'
48+
return out
49+
50+
def _showfields_add_regular_fields(self, parts):
51+
"helper for __unicode__"
52+
done_fields = set()
53+
for field in self._meta.fields + self._meta.many_to_many:
54+
if field.name in self.polymorphic_internal_model_fields or '_ptr' in field.name:
55+
continue
56+
if field.name in done_fields:
57+
continue # work around django diamond inheritance problem
58+
done_fields.add(field.name)
59+
60+
out = field.name
61+
62+
# if this is the standard primary key named "id", print it as we did with older versions of django_polymorphic
63+
if field.primary_key and field.name == 'id' and type(field) == models.AutoField:
64+
out += ' ' + str(getattr(self, field.name))
65+
66+
# otherwise, display it just like all other fields (with correct type, shortened content etc.)
67+
else:
68+
if self.polymorphic_showfield_type:
69+
out += ' (' + type(field).__name__
70+
if field.primary_key:
71+
out += '/pk'
72+
out += ')'
73+
74+
if self.polymorphic_showfield_content:
75+
out += self._showfields_get_content(field.name, type(field))
76+
77+
parts.append((False, out, ','))
78+
79+
def _showfields_add_dynamic_fields(self, field_list, title, parts):
80+
"helper for __unicode__"
81+
parts.append((True, '- ' + title, ':'))
82+
for field_name in field_list:
83+
out = field_name
84+
content = getattr(self, field_name)
85+
if self.polymorphic_showfield_type:
86+
out += ' (' + type(content).__name__ + ')'
87+
if self.polymorphic_showfield_content:
88+
out += self._showfields_get_content(field_name)
89+
90+
parts.append((False, out, ','))
91+
92+
def __unicode__(self):
93+
# create list ("parts") containing one tuple for each title/field:
94+
# ( bool: new section , item-text , separator to use after item )
95+
96+
# start with model name
97+
parts = [(True, self.__class__.__name__, ':')]
98+
99+
# add all regular fields
100+
self._showfields_add_regular_fields(parts)
101+
102+
# add annotate fields
103+
if hasattr(self, 'polymorphic_annotate_names'):
104+
self._showfields_add_dynamic_fields(self.polymorphic_annotate_names, 'Ann', parts)
105+
106+
# add extra() select fields
107+
if hasattr(self, 'polymorphic_extra_select_names'):
108+
self._showfields_add_dynamic_fields(self.polymorphic_extra_select_names, 'Extra', parts)
109+
110+
# format result
111+
112+
indent = len(self.__class__.__name__) + 5
113+
indentstr = ''.rjust(indent)
114+
out = ''
115+
xpos = 0
116+
possible_line_break_pos = None
117+
118+
for i in range(len(parts)):
119+
new_section, p, separator = parts[i]
120+
final = (i == len(parts) - 1)
121+
if not final:
122+
next_new_section, _, _ = parts[i + 1]
123+
124+
if (self.polymorphic_showfield_max_line_width
125+
and xpos + len(p) > self.polymorphic_showfield_max_line_width
126+
and possible_line_break_pos != None):
127+
rest = out[possible_line_break_pos:]
128+
out = out[:possible_line_break_pos]
129+
out += '\n' + indentstr + rest
130+
xpos = indent + len(rest)
131+
132+
out += p
133+
xpos += len(p)
134+
135+
if not final:
136+
if not next_new_section:
137+
out += separator
138+
xpos += len(separator)
139+
out += ' '
140+
xpos += 1
141+
142+
if not new_section:
143+
possible_line_break_pos = len(out)
144+
145+
return '<' + out + '>'
146+
147+
148+
class ShowFieldType(ShowFieldBase):
149+
""" model mixin that shows the object's class and it's field types """
150+
polymorphic_showfield_type = True
151+
152+
153+
class ShowFieldContent(ShowFieldBase):
154+
""" model mixin that shows the object's class, it's fields and field contents """
155+
polymorphic_showfield_content = True
156+
157+
158+
class ShowFieldTypeAndContent(ShowFieldBase):
159+
""" model mixin, like ShowFieldContent, but also show field types """
160+
polymorphic_showfield_type = True
161+
polymorphic_showfield_content = True
162+
163+
164+
# compatibility with old class names
165+
ShowFieldTypes = ShowFieldType
166+
ShowFields = ShowFieldContent
167+
ShowFieldsAndTypes = ShowFieldTypeAndContent

0 commit comments

Comments
 (0)