Extending Django CMS Page model - part II
... or how to use the extended model in your templates and especially in the built-in navigation
The problem: As you can see in the previous post there is a very simple way to extend the page model with some custom fields without changing the core code. But how to use your custom fields inside your templates? If you have an instance of the Page model everything is fine. You can just access its properties and everything is fine. Unfortunately there is a problem if you try it inside a custom template used for show_menu template tag.
Speciality: I was really surprised when I tried to access my custom properties inside the mentioned above template and nothing happened. After some investigation I found that the elements in show_menu are not instances of the Page model but of NavigationNode. And even more surprised that NavigationNode does not contain instance of the Page model in its properties. So I was in need to extend the NavigationNode class.
Solution: First of all I decided to make it easier to access the custom properties I created before, so I added the following code to it:
class PageAvatars(models.Model):
page = models.ForeignKey(Page, unique=True, verbose_name=_("Page"),
editable=False, related_name='extended_fields')
big_avatar = FileBrowseField(_(u'Big Avatar'), max_length=255, blank=True)
small_avatar = FileBrowseField(_(u'Small Avatar'), max_length=255, blank=True)
def _big_avatar(obj):
for e_f in obj.extended_fields.all():
return e_f.big_avatar
return None
Page._big_avatar = _big_avatar
Page.big_avatar = property(lambda u: u._big_avatar())
from menus.base import NavigationNode
NavigationNode.page_instance = lambda u: Page.objects.filter(pk = u.id)[0]
{% for child in children %}
{{child.page_instance.big_avatar}}
{% endfor %}
Final words: I need to confess that I am really, really amazed how simply things can be done in Django and Django CMS. It is really awesome. I hope that you will find this post really helpful and useful. And as always do not be afraid to propose a better solutions or to ask for deeper explanation if something is not clear enough.