Commits

Anonymous committed 0aa9fba

Added Page.url as a cached property
Switch to stdlib json
Tidied with flake8

Comments (0)

Files changed (1)

gnocchi/cms/models.py

+
+import json
+
 from django.db import models
+from django.db.models.signals import post_save
 from django.contrib.contenttypes import generic
-from django.utils.safestring import mark_safe
-from django.utils import simplejson
+from django.core.cache import cache
 from django.core.validators import RegexValidator, ValidationError
 from django.core.urlresolvers import reverse
 from django.template import Template as DjangoTemplate
 from django.template.loader import get_template
+from django.utils.functional import cached_property
+from django.utils.safestring import mark_safe
 
 # Used to clear cache on change
-from django.db.models.signals import post_save
 from gnocchi.cms import settings
-from django.core.cache import cache
-
 from gnocchi.tools.attr import AttrHelper
 
 # Translations
 from django.utils.translation import ugettext_lazy as _
 
-#
-# DB stored templates
-#
 
 class Template(models.Model):
     '''A Database backed Template'''
         verbose_name = _('template')
         verbose_name_plural = _('templates')
         ordering = ('path',)
+
     def __unicode__(self):
         return self.path
+
     def render(self, context):
         return DjangoTemplate(self.content).render(context)
 
-#
-# URL tree model
-#
 
 class PageManager(models.Manager):
     def published(self):
         '''Filter for only published pages'''
         return self.get_query_set().filter(is_published=True)
 
+
 class Page(models.Model, AttrHelper):
     '''Heirarchy of objects providing content'''
     parent = models.ForeignKey('self', blank=True, null=True,
         related_name='children')
     path = models.SlugField(blank=True,
-        help_text = 'This will form part of the URL')
+        help_text='This will form part of the URL')
     title = models.CharField(max_length=512)
 
     is_published = models.BooleanField(default=True)
         return '/%s' % '/'.join(paths)
     get_absolute_url.short_description = 'url'
 
+    @cached_property
+    def url(self):
+        return self.get_absolute_url()
+
     def get_template(self):
         '''Returns the template to render this page'''
         if self.template_id:
         return get_template(settings.DEFAULT_TEMPLATE)
 
     ##
-    ## Tree-related functions
+    # Tree-related functions
     ##
     def is_root(self):
         '''Return True if this is a root Page'''
         return Page.objects.published().filter(parent=None)
 
     ##
-    ## Permissions hook
+    # Permissions hook
     ##
     def can_view(self, user):
         '''Test if a User has permission to view this page.'''
             # No explicit rule == Permit
             return True
 
+
 class Fragment(models.Model):
     '''Content fragment of a Page'''
     page = models.ForeignKey(Page)
     name = models.CharField(max_length=200)
     content = models.TextField(blank=True)
+
     class Meta:
         verbose_name = _('fragment')
         verbose_name_plural = _('fragments')
             ('page', 'name',)
         )
 
+
 class PageAccess(models.Model):
     page = models.ForeignKey(Page)
     # who does this apply to?
     # What do we say?
     permit = models.BooleanField(default=True)
 
-    def __unicode__(self):
-        return u'Access for %s to %s' % (self.group or 'Default', self.page)
     class Meta:
         unique_together = (
             ('page', 'group',),
         )
         ordering = ('group',)
 
-#
-# Style Sheets
-#
+    def __unicode__(self):
+        return u'Access for %s to %s' % (self.group or 'Default', self.page)
+
 
 class StyleSheet(models.Model):
     '''Helpful wrapper for DB stored StyleSheets with Templating'''
     name = models.SlugField()
     description = models.CharField(max_length=1024, blank=True)
     content = models.TextField(blank=True)
+
     class Meta:
         verbose_name = _('style sheet')
         verbose_name_plural = _('style sheets')
+
     def __unicode__(self):
         return u'[%s] %s' % (self.name, self.description,)
+
     def get_absolute_url(self):
         return reverse('gnocchi.cms.views.css', kwargs={'name': self.name})
+
     def render(self, context):
         return DjangoTemplate(self.content).render(context)
 
-#
-# Global context variables
-#
 
 class ContextVariable(models.Model):
     TYPE_CHOICES = (
         'int': int,
         'float': float,
         'str': mark_safe,
-        'json': simplejson.loads
+        'json': json.loads
     }
     # functions to convert to storage [default: unicode()]
     STORE_MAP = {
-        'json': simplejson.dumps
+        'json': json.dumps
     }
     name = models.CharField(max_length=64, validators=[
         RegexValidator(r'^\w+$'),
         RegexValidator(r'^\w+$'),
     ])
     description = models.CharField(max_length=200, blank=True)
-    type = models.CharField(max_length=32, choices = TYPE_CHOICES)
+    type = models.CharField(max_length=32, choices=TYPE_CHOICES)
     value = models.CharField(max_length=1024)
+
     class Meta:
         verbose_name = _('context variable')
         verbose_name_plural = _('context variables')
+
     def clean(self):
         try:
             self.get_value()
         except Exception, e:
-            raise ValidationError, "Value %r not valid for type %s (%r)" % (
+            raise ValidationError("Value %r not valid for type %s (%r)" % (
                 self.value, self.type, e
-            )
+            ))
         if not isinstance(self.value, basestring):
             self.value = self.set_value(self.value)
 
     def get_value(self):
         return self.LOAD_MAP.get(self.type, lambda x: x)(self.value)
+
     def set_value(self, value):
         return self.STORE_MAP.get(self.type, unicode)(value)
+
     def full_name(self):
         return u'%s.%s' % (self.group, self.name,)
 
+
 def cv_clear_cache(sender, **kwargs):
     cache.delete('gnocchi-%s' % settings.CV_NAMESPACE)
 post_save.connect(cv_clear_cache, sender=ContextVariable)