8000 Fixed #6340 -- Reorder models to support dumpdata (#6341) · django-cms/django-cms@9e60ff1 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e60ff1

Browse files
heppstuxczpython
authored andcommitted
Fixed #6340 -- Reorder models to support dumpdata (#6341)
1 parent bf8e9d6 commit 9e60ff1

File tree

3 files changed

+121
-110
lines changed

3 files changed

+121
-110
lines changed

CHANGELOG.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
=== 3.5.3 (unreleased) ===
2+
3+
* Fixed ``TreeNode.DoesNotExist`` exception raised when exporting
4+
and loading database contents via ``dumpdata`` and ``loaddata``.
5+
6+
17
=== 3.5.2 (2018-04-11) ===
28

39
* Fixed a bug where shortcuts menu entry would stop working after toolbar reload

cms/models/pagemodel.py

Lines changed: 109 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,115 @@
3535
logger = getLogger(__name__)
3636

3737

38+
@python_2_unicode_compatible
39+
class TreeNode(MP_Node):
40+
41+
parent = models.ForeignKey(
42+
'self',
43+
on_delete=models.CASCADE,
44+
blank=True,
45+
null=True,
46+
related_name='children',
47+
db_index=True,
48+
)
49+
site = models.ForeignKey(
50+
Site,
51+
on_delete=models.CASCADE,
52+
verbose_name=_("site"),
53+
related_name='djangocms_nodes',
54+
db_index=True,
55+
)
56+
57+
objects = PageNodeManager()
58+
59+
class Meta:
60+
app_label = 'cms'
61+
ordering = ('path',)
62+
default_permissions = []
63+
64+
def __str__(self):
65+
return self.path
66+
67+
@cached_property
68+
def item(self):
69+
return self.get_item()
70+
71+
def get_item(self):
72+
# Paving the way...
73+
return Page.objects.get(node=self, publisher_is_draft=True)
74+
75+
@property
76+
def is_branch(self):
77+
return bool(self.numchild)
78+
79+
def get_ancestor_paths(self):
80+
paths = frozenset(
81+
self.path[0:pos]
82+
for pos in range(0, len(self.path), self.steplen)[1:]
83+
)
84+
return paths
85+
86+
def add_child(self, **kwargs):
87+
if len(kwargs) == 1 and 'instance' in kwargs:
88+
kwargs['instance'].parent = self
89+
else:
90+
kwargs['parent'] = self
91+
return super(TreeNode, self).add_child(**kwargs)
92+
93+
def add_sibling(self, pos=None, *args, **kwargs):
94+
if len(kwargs) == 1 and 'instance' in kwargs:
95+
kwargs['instance'].parent_id = self.parent_id
96+
else:
97+
kwargs['parent_id'] = self.parent_id
98+
return super(TreeNode, self).add_sibling(*args, **kwargs)
99+
100+
def update(self, **data):
101+
cls = self.__class__
102+
cls.objects.filter(pk=self.pk).update(**data)
103+
104+
for field, value in data.items():
105+
setattr(self, field, value)
106+
return
107+
108+
def get_cached_ancestors(self):
109+
if self._has_cached_hierarchy():
110+
return self._ancestors
111+
return []
112+
113+
def get_cached_descendants(self):
114+
if self._has_cached_hierarchy():
115+
return self._descendants
116+
return []
117+
118+
def _reload(self):
119+
"""
120+
Reload a page node from the database
121+
"""
122+
return self.__class__.objects.get(pk=self.pk)
123+
124+
def _has_cached_hierarchy(self):
125+
return hasattr(self, '_descendants') and hasattr(self, '_ancestors')
126+
127+
def _set_hierarchy(self, nodes, ancestors=None):
128+
if self.is_branch:
129+
self._descendants = [node for node in nodes
130+
if node.path.startswith(self.path)
131+
and node.depth > self.depth]
132+
else:
133+
self._descendants = []
134+
135+
if self.is_root():
136+
self._ancestors = []
137+
else:
138+
self._ancestors = ancestors
139+
140+
children = (node for node in self._descendants
141+
if node.depth == self.depth + 1)
142+
143+
for child in children:
144+
child._set_hierarchy(self._descendants, ancestors=([self] + self._ancestors))
145+
146+
38147
@python_2_unicode_compatible
39148
class Page(models.Model):
40149
"""
@@ -1586,112 +1695,3 @@ def get_root_page(cls, site):
15861695

15871696 def is_potential_home(self):
15881697
return False
1589-
1590-
1591-
@python_2_unicode_compatible
1592-
class TreeNode(MP_Node):
1593-
1594-
parent = models.ForeignKey(
1595-
'self',
1596-
on_delete=models.CASCADE,
1597-
blank=True,
1598-
null=True,
1599-
related_name='children',
1600-
db_index=True,
1601-
)
1602-
site = models.ForeignKey(
1603-
Site,
1604-
on_delete=models.CASCADE,
1605-
verbose_name=_("site"),
1606-
related_name='djangocms_nodes',
1607-
db_index=True,
1608-
)
1609-
1610-
objects = PageNodeManager()
1611-
1612-
class Meta:
1613-
app_label = 'cms'
1614-
ordering = ('path',)
1615-
default_permissions = []
1616-
1617-
def __str__(self):
1618-
return self.path
1619-
1620-
@cached_property
1621-
def item(self):
1622-
return self.get_item()
1623-
1624-
def get_item(self):
1625-
# Paving the way...
1626-
return Page.objects.get(node=self, publisher_is_draft=True)
1627-
1628-
@property
1629-
def is_branch(self):
1630-
return bool(self.numchild)
1631-
1632-
def get_ancestor_paths(self):
1633-
paths = frozenset(
1634-
self.path[0:pos]
1635-
for pos in range(0, len(self.path), self.steplen)[1:]
1636-
)
1637-
return paths
1638-
1639-
def add_child(self, **kwargs):
1640-
if len(kwargs) == 1 and 'instance' in kwargs:
1641-
kwargs['instance'].parent = self
1642-
else:
1643-
kwargs['parent'] = self
1644-
return super(TreeNode, self).add_child(**kwargs)
1645-
1646-
def add_sibling(self, pos=None, *args, **kwargs):
1647-
if len(kwargs) == 1 and 'instance' in kwargs:
1648-
kwargs['instance'].parent_id = self.parent_id
1649-
else:
1650-
kwargs['parent_id'] = self.parent_id
1651-
return super(TreeNode, self).add_sibling(*args, **kwargs)
1652-
1653-
def update(self, **data):
1654-
cls = self.__class__
1655-
cls.objects.filter(pk=self.pk).update(**data)
1656-
1657-
for field, value in data.items():
1658-
setattr(self, field, value)
1659-
return
1660-
1661-
def get_cached_ancestors(self):
1662-
if self._has_cached_hierarchy():
1663-
return self._ancestors
1664-
return []
1665-
1666-
def get_cached_descendants(self):
1667-
if self._has_cached_hierarchy():
1668-
return self._descendants
1669-
return []
1670-
1671-
def _reload(self):
1672-
"""
1673-
Reload a page node from the database
1674-
"""
1675-
return self.__class__.objects.get(pk=self.pk)
1676-
1677-
def _has_cached_hierarchy(self):
1678-
return hasattr(self, '_descendants') and hasattr(self, '_ancestors')
1679-
1680-
def _set_hierarchy(self, nodes, ancestors=None):
1681-
if self.is_branch:
1682-
self._descendants = [node for node in nodes
1683-
if node.path.startswith(self.path)
1684-
and node.depth > self.depth]
1685-
else:
1686-
self._descendants = []
1687-
1688-
if self.is_root():
1689-
self._ancestors = []
1690-
else:
1691-
self._ancestors = ancestors
1692-
1693-
children = (node for node in self._descendants
1694-
if node.depth == self.depth + 1)
1695-
1696-
for child in children:
1697-
child._set_hierarchy(self._descendants, ancestors=([self] + self._ancestors))

cms/tests/test_fixture_loading.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99

1010
from django.core.management import call_command
1111

12+
from cms.models import CMSPlugin, Page, Placeholder, TreeNode
1213
from cms.test_utils.fixtures.navextenders import NavextendersFixture
1314
from cms.test_utils.testcases import CMSTestCase
14-
from cms.models import Page, Placeholder, CMSPlugin
1515

1616

1717
class FixtureTestCase(NavextendersFixture, CMSTestCase):
@@ -27,19 +27,24 @@ def test_fixture_load(self):
2727
call_command('dumpdata', 'cms', indent=3, stdout=output)
2828
original_ph = Placeholder.objects.count()
2929
original_pages = Page.objects.count()
30+
original_tree_nodes = TreeNode.objects.count()
3031
original_plugins = CMSPlugin.objects.count()
3132
Page.objects.all().delete()
33+
TreeNode.objects.all().delete()
3234
output.seek(0)
3335
with codecs.open(dump[1], 'w', 'utf-8') as dumpfile:
3436
dumpfile.write(output.read())
3537

38+
self.assertEqual(0, TreeNode.objects.count())
3639
self.assertEqual(0, Page.objects.count())
3740
self.assertEqual(0, Placeholder.objects.count())
3841
# Transaction disable, otherwise the connection it the test would be
3942
# isolated from the data loaded in the different command connection
4043
call_command('loaddata', dump[1], commit=False, stdout=output)
4144
self.assertEqual(10, Page.objects.count())
4245
self.assertEqual(original_pages, Page.objects.count())
46+
self.assertEqual(5, TreeNode.objects.count())
47+
self.assertEqual(original_tree_nodes, TreeNode.objects.count())
4348
# Placeholder number may differ if signals does not correctly handle
4449
# load data command
4550
self.assertEqual(original_ph, Placeholder.objects.count())

0 commit comments

Comments
 (0)
0