Splitting models into submodules beside models.base.
authorJoseph Spiros <joseph.spiros@ithinksw.com>
Wed, 23 Jun 2010 16:26:10 +0000 (12:26 -0400)
committerJoseph Spiros <joseph.spiros@ithinksw.com>
Wed, 23 Jun 2010 16:26:10 +0000 (12:26 -0400)
models/__init__.py
models/base.py
models/collections.py [new file with mode: 0644]
models/nodes.py [new file with mode: 0644]
models/pages.py [new file with mode: 0644]

index b934cda..b9ea3ac 100644 (file)
@@ -1 +1,11 @@
-from philo.models.base import *
\ No newline at end of file
+from philo.models.base import *
+from philo.models.collections import *
+from philo.models.nodes import *
+from philo.models.pages import *
+from django.contrib.auth.models import User, Group
+from django.contrib.sites.models import Site
+
+
+register_value_model(User)
+register_value_model(Group)
+register_value_model(Site)
\ No newline at end of file
index bd55e95..5ca9d93 100644 (file)
@@ -1,25 +1,9 @@
-# encoding: utf-8
-from django.utils.translation import ugettext_lazy as _
-from django.contrib.auth.models import User, Group
-from django.contrib.contenttypes import generic
-from django.contrib.contenttypes.models import ContentType
 from django.db import models
-from django.contrib.sites.models import Site
-from philo.utils import fattr
-from django.template import add_to_builtins as register_templatetags
-from django.template import Template as DjangoTemplate
-from django.template import TemplateDoesNotExist
-from django.template import Context, RequestContext
-from django.core.exceptions import ObjectDoesNotExist
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
 from django.utils import simplejson as json
+from django.core.exceptions import ObjectDoesNotExist
 from UserDict import DictMixin
-from philo.templatetags.containers import ContainerNode
-from django.template.loader_tags import ExtendsNode, ConstantIncludeNode, IncludeNode
-from django.template.loader import get_template
-from django.http import Http404, HttpResponse, HttpResponseServerError, HttpResponseRedirect
-from django.core.servers.basehttp import FileWrapper
-from django.conf import settings
-from philo.validators import RedirectValidator
 
 
 def register_value_model(model):
@@ -106,43 +90,6 @@ class Entity(models.Model):
                app_label = 'philo'
 
 
-class Collection(models.Model):
-       name = models.CharField(max_length=255)
-       description = models.TextField(blank=True, null=True)
-       
-       @fattr(short_description='Members')
-       def get_count(self):
-               return self.members.count()
-       
-       def __unicode__(self):
-               return self.name
-       
-       class Meta:
-               app_label = 'philo'
-
-
-class CollectionMemberManager(models.Manager):
-       use_for_related_fields = True
-
-       def with_model(self, model):
-               return model._default_manager.filter(pk__in=self.filter(member_content_type=ContentType.objects.get_for_model(model)).values_list('member_object_id', flat=True))
-
-
-class CollectionMember(models.Model):
-       objects = CollectionMemberManager()
-       collection = models.ForeignKey(Collection, related_name='members')
-       index = models.PositiveIntegerField(verbose_name='Index', help_text='This will determine the ordering of the item within the collection. (Optional)', null=True, blank=True)
-       member_content_type = models.ForeignKey(ContentType, verbose_name='Member type')
-       member_object_id = models.PositiveIntegerField(verbose_name='Member ID')
-       member = generic.GenericForeignKey('member_content_type', 'member_object_id')
-       
-       def __unicode__(self):
-               return u'%s - %s' % (self.collection, self.member)
-       
-       class Meta:
-               app_label = 'philo'
-
-
 class TreeManager(models.Manager):
        use_for_related_fields = True
        
@@ -257,198 +204,4 @@ class InheritableTreeEntity(TreeEntity):
        
        class Meta:
                abstract = True
-               app_label = 'philo'
-
-
-class Node(InheritableTreeEntity):
-       accepts_subpath = False
-       
-       def render_to_response(self, request, path=None, subpath=None):
-               return HttpResponseServerError()
-               
-       class Meta:
-               unique_together = (('parent', 'slug'),)
-               app_label = 'philo'
-
-
-class MultiNode(Node):
-       accepts_subpath = True
-       
-       urlpatterns = []
-       
-       def render_to_response(self, request, path=None, subpath=None):
-               if not subpath:
-                       subpath = ""
-               subpath = "/" + subpath
-               from django.core.urlresolvers import resolve
-               view, args, kwargs = resolve(subpath, urlconf=self)
-               return view(request, *args, **kwargs)
-       
-       class Meta:
-               abstract = True
-               app_label = 'philo'
-
-
-class Redirect(Node):
-       STATUS_CODES = (
-               (302, 'Temporary'),
-               (301, 'Permanent'),
-       )
-       target = models.CharField(max_length=200,validators=[RedirectValidator()])
-       status_code = models.IntegerField(choices=STATUS_CODES, default=302, verbose_name='redirect type')
-       
-       def render_to_response(self, request, path=None, subpath=None):
-               response = HttpResponseRedirect(self.target)
-               response.status_code = self.status_code
-               return response
-       
-       class Meta:
-               app_label = 'philo'
-
-
-class File(Node):
-       """ For storing arbitrary files """
-       mimetype = models.CharField(max_length=255)
-       file = models.FileField(upload_to='philo/files/%Y/%m/%d')
-       
-       def render_to_response(self, request, path=None, subpath=None):
-               wrapper = FileWrapper(self.file)
-               response = HttpResponse(wrapper, content_type=self.mimetype)
-               response['Content-Length'] = self.file.size
-               return response
-       
-       class Meta:
-               app_label = 'philo'
-
-
-class Template(TreeModel):
-       name = models.CharField(max_length=255)
-       documentation = models.TextField(null=True, blank=True)
-       mimetype = models.CharField(max_length=255, null=True, blank=True, help_text='Default: %s' % settings.DEFAULT_CONTENT_TYPE)
-       code = models.TextField(verbose_name='django template code')
-       
-       @property
-       def origin(self):
-               return 'philo.models.Template: ' + self.path
-       
-       @property
-       def django_template(self):
-               return DjangoTemplate(self.code)
-       
-       @property
-       def containers(self):
-               """
-               Returns a tuple where the first item is a list of names of contentlets referenced by containers,
-               and the second item is a list of tuples of names and contenttypes of contentreferences referenced by containers.
-               This will break if there is a recursive extends or includes in the template code.
-               Due to the use of an empty Context, any extends or include tags with dynamic arguments probably won't work.
-               """
-               def container_nodes(template):
-                       def nodelist_container_nodes(nodelist):
-                               nodes = []
-                               for node in nodelist:
-                                       try:
-                                               for nodelist_name in ('nodelist', 'nodelist_loop', 'nodelist_empty', 'nodelist_true', 'nodelist_false', 'nodelist_main'):
-                                                       if hasattr(node, nodelist_name):
-                                                               nodes.extend(nodelist_container_nodes(getattr(node, nodelist_name)))
-                                               if isinstance(node, ContainerNode):
-                                                       nodes.append(node)
-                                               elif isinstance(node, ExtendsNode):
-                                                       extended_template = node.get_parent(Context())
-                                                       if extended_template:
-                                                               nodes.extend(container_nodes(extended_template))
-                                               elif isinstance(node, ConstantIncludeNode):
-                                                       included_template = node.template
-                                                       if included_template:
-                                                               nodes.extend(container_nodes(included_template))
-                                               elif isinstance(node, IncludeNode):
-                                                       included_template = get_template(node.template_name.resolve(Context()))
-                                                       if included_template:
-                                                               nodes.extend(container_nodes(included_template))
-                                       except:
-                                               pass # fail for this node
-                               return nodes
-                       return nodelist_container_nodes(template.nodelist)
-               all_nodes = container_nodes(self.django_template)
-               contentlet_node_names = set([node.name for node in all_nodes if not node.references])
-               contentreference_node_names = []
-               contentreference_node_specs = []
-               for node in all_nodes:
-                       if node.references and node.name not in contentreference_node_names:
-                               contentreference_node_specs.append((node.name, node.references))
-                               contentreference_node_names.append(node.name)
-               return contentlet_node_names, contentreference_node_specs
-       
-       def __unicode__(self):
-               return self.get_path(u' › ', 'name')
-       
-       @staticmethod
-       @fattr(is_usable=True)
-       def loader(template_name, template_dirs=None): # load_template_source
-               try:
-                       template = Template.objects.get_with_path(template_name)
-               except Template.DoesNotExist:
-                       raise TemplateDoesNotExist(template_name)
-               return (template.code, template.origin)
-       
-       class Meta:
-               app_label = 'philo'
-
-
-class Page(Node):
-       """
-       Represents a page - something which is rendered according to a template. The page will have a number of related Contentlets depending on the template selected - but these will appear only after the page has been saved with that template.
-       """
-       template = models.ForeignKey(Template, related_name='pages')
-       title = models.CharField(max_length=255)
-       
-       def render_to_response(self, request, path=None, subpath=None):
-               return HttpResponse(self.template.django_template.render(RequestContext(request, {'page': self})), mimetype=self.template.mimetype)
-       
-       def __unicode__(self):
-               return self.get_path(u' › ', 'title')
-       
-       class Meta:
-               app_label = 'philo'
-
-
-# the following line enables the selection of a node as the root for a given django.contrib.sites Site object
-models.ForeignKey(Node, related_name='sites', null=True, blank=True).contribute_to_class(Site, 'root_node')
-
-
-class Contentlet(models.Model):
-       page = models.ForeignKey(Page, related_name='contentlets')
-       name = models.CharField(max_length=255)
-       content = models.TextField()
-       dynamic = models.BooleanField(default=False)
-       
-       def __unicode__(self):
-               return self.name
-       
-       class Meta:
-               app_label = 'philo'
-
-
-class ContentReference(models.Model):
-       page = models.ForeignKey(Page, related_name='contentreferences')
-       name = models.CharField(max_length=255)
-       content_type = models.ForeignKey(ContentType, verbose_name='Content type')
-       content_id = models.PositiveIntegerField(verbose_name='Content ID', blank=True, null=True)
-       content = generic.GenericForeignKey('content_type', 'content_id')
-       
-       def __unicode__(self):
-               return self.name
-       
-       class Meta:
-               app_label = 'philo'
-
-
-register_templatetags('philo.templatetags.containers')
-
-
-register_value_model(User)
-register_value_model(Group)
-register_value_model(Site)
-register_value_model(Collection)
-register_value_model(Template)
-register_value_model(Page)
+               app_label = 'philo'
\ No newline at end of file
diff --git a/models/collections.py b/models/collections.py
new file mode 100644 (file)
index 0000000..61b2608
--- /dev/null
@@ -0,0 +1,45 @@
+from django.db import models
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
+from philo.models.base import register_value_model
+from philo.utils import fattr
+
+
+class Collection(models.Model):
+       name = models.CharField(max_length=255)
+       description = models.TextField(blank=True, null=True)
+       
+       @fattr(short_description='Members')
+       def get_count(self):
+               return self.members.count()
+       
+       def __unicode__(self):
+               return self.name
+       
+       class Meta:
+               app_label = 'philo'
+
+
+class CollectionMemberManager(models.Manager):
+       use_for_related_fields = True
+
+       def with_model(self, model):
+               return model._default_manager.filter(pk__in=self.filter(member_content_type=ContentType.objects.get_for_model(model)).values_list('member_object_id', flat=True))
+
+
+class CollectionMember(models.Model):
+       objects = CollectionMemberManager()
+       collection = models.ForeignKey(Collection, related_name='members')
+       index = models.PositiveIntegerField(verbose_name='Index', help_text='This will determine the ordering of the item within the collection. (Optional)', null=True, blank=True)
+       member_content_type = models.ForeignKey(ContentType, verbose_name='Member type')
+       member_object_id = models.PositiveIntegerField(verbose_name='Member ID')
+       member = generic.GenericForeignKey('member_content_type', 'member_object_id')
+       
+       def __unicode__(self):
+               return u'%s - %s' % (self.collection, self.member)
+       
+       class Meta:
+               app_label = 'philo'
+
+
+register_value_model(Collection)
\ No newline at end of file
diff --git a/models/nodes.py b/models/nodes.py
new file mode 100644 (file)
index 0000000..6bdc85d
--- /dev/null
@@ -0,0 +1,66 @@
+from django.db import models
+from django.http import HttpResponse, HttpResponseServerError, HttpResponseRedirect
+from django.core.servers.basehttp import FileWrapper
+from philo.models.base import InheritableTreeEntity
+from philo.validators import RedirectValidator
+
+
+class Node(InheritableTreeEntity):
+       accepts_subpath = False
+       
+       def render_to_response(self, request, path=None, subpath=None):
+               return HttpResponseServerError()
+               
+       class Meta:
+               unique_together = (('parent', 'slug'),)
+               app_label = 'philo'
+
+
+class MultiNode(Node):
+       accepts_subpath = True
+       
+       urlpatterns = []
+       
+       def render_to_response(self, request, path=None, subpath=None):
+               if not subpath:
+                       subpath = ""
+               subpath = "/" + subpath
+               from django.core.urlresolvers import resolve
+               view, args, kwargs = resolve(subpath, urlconf=self)
+               return view(request, *args, **kwargs)
+       
+       class Meta:
+               abstract = True
+               app_label = 'philo'
+
+
+class Redirect(Node):
+       STATUS_CODES = (
+               (302, 'Temporary'),
+               (301, 'Permanent'),
+       )
+       target = models.CharField(max_length=200,validators=[RedirectValidator()])
+       status_code = models.IntegerField(choices=STATUS_CODES, default=302, verbose_name='redirect type')
+       
+       def render_to_response(self, request, path=None, subpath=None):
+               response = HttpResponseRedirect(self.target)
+               response.status_code = self.status_code
+               return response
+       
+       class Meta:
+               app_label = 'philo'
+
+
+class File(Node):
+       """ For storing arbitrary files """
+       mimetype = models.CharField(max_length=255)
+       file = models.FileField(upload_to='philo/files/%Y/%m/%d')
+       
+       def render_to_response(self, request, path=None, subpath=None):
+               wrapper = FileWrapper(self.file)
+               response = HttpResponse(wrapper, content_type=self.mimetype)
+               response['Content-Length'] = self.file.size
+               return response
+       
+       class Meta:
+               app_label = 'philo'
\ No newline at end of file
diff --git a/models/pages.py b/models/pages.py
new file mode 100644 (file)
index 0000000..3435511
--- /dev/null
@@ -0,0 +1,146 @@
+# encoding: utf-8
+from django.db import models
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
+from django.conf import settings
+from django.template import add_to_builtins as register_templatetags
+from django.template import Template as DjangoTemplate
+from django.template import TemplateDoesNotExist
+from django.template import Context, RequestContext
+from django.template.loader import get_template
+from django.template.loader_tags import ExtendsNode, ConstantIncludeNode, IncludeNode
+from django.http import HttpResponse
+from django.contrib.sites.models import Site
+from philo.models.base import TreeModel, register_value_model
+from philo.models.nodes import Node
+from philo.utils import fattr
+from philo.templatetags.containers import ContainerNode
+
+
+class Template(TreeModel):
+       name = models.CharField(max_length=255)
+       documentation = models.TextField(null=True, blank=True)
+       mimetype = models.CharField(max_length=255, null=True, blank=True, help_text='Default: %s' % settings.DEFAULT_CONTENT_TYPE)
+       code = models.TextField(verbose_name='django template code')
+       
+       @property
+       def origin(self):
+               return 'philo.models.Template: ' + self.path
+       
+       @property
+       def django_template(self):
+               return DjangoTemplate(self.code)
+       
+       @property
+       def containers(self):
+               """
+               Returns a tuple where the first item is a list of names of contentlets referenced by containers,
+               and the second item is a list of tuples of names and contenttypes of contentreferences referenced by containers.
+               This will break if there is a recursive extends or includes in the template code.
+               Due to the use of an empty Context, any extends or include tags with dynamic arguments probably won't work.
+               """
+               def container_nodes(template):
+                       def nodelist_container_nodes(nodelist):
+                               nodes = []
+                               for node in nodelist:
+                                       try:
+                                               for nodelist_name in ('nodelist', 'nodelist_loop', 'nodelist_empty', 'nodelist_true', 'nodelist_false', 'nodelist_main'):
+                                                       if hasattr(node, nodelist_name):
+                                                               nodes.extend(nodelist_container_nodes(getattr(node, nodelist_name)))
+                                               if isinstance(node, ContainerNode):
+                                                       nodes.append(node)
+                                               elif isinstance(node, ExtendsNode):
+                                                       extended_template = node.get_parent(Context())
+                                                       if extended_template:
+                                                               nodes.extend(container_nodes(extended_template))
+                                               elif isinstance(node, ConstantIncludeNode):
+                                                       included_template = node.template
+                                                       if included_template:
+                                                               nodes.extend(container_nodes(included_template))
+                                               elif isinstance(node, IncludeNode):
+                                                       included_template = get_template(node.template_name.resolve(Context()))
+                                                       if included_template:
+                                                               nodes.extend(container_nodes(included_template))
+                                       except:
+                                               raise # fail for this node
+                               return nodes
+                       return nodelist_container_nodes(template.nodelist)
+               all_nodes = container_nodes(self.django_template)
+               contentlet_node_names = set([node.name for node in all_nodes if not node.references])
+               contentreference_node_names = []
+               contentreference_node_specs = []
+               for node in all_nodes:
+                       if node.references and node.name not in contentreference_node_names:
+                               contentreference_node_specs.append((node.name, node.references))
+                               contentreference_node_names.append(node.name)
+               return contentlet_node_names, contentreference_node_specs
+       
+       def __unicode__(self):
+               return self.get_path(u' › ', 'name')
+       
+       @staticmethod
+       @fattr(is_usable=True)
+       def loader(template_name, template_dirs=None): # load_template_source
+               try:
+                       template = Template.objects.get_with_path(template_name)
+               except Template.DoesNotExist:
+                       raise TemplateDoesNotExist(template_name)
+               return (template.code, template.origin)
+       
+       class Meta:
+               app_label = 'philo'
+
+
+class Page(Node):
+       """
+       Represents a page - something which is rendered according to a template. The page will have a number of related Contentlets depending on the template selected - but these will appear only after the page has been saved with that template.
+       """
+       template = models.ForeignKey(Template, related_name='pages')
+       title = models.CharField(max_length=255)
+       
+       def render_to_response(self, request, path=None, subpath=None):
+               return HttpResponse(self.template.django_template.render(RequestContext(request, {'page': self})), mimetype=self.template.mimetype)
+       
+       def __unicode__(self):
+               return self.get_path(u' › ', 'title')
+       
+       class Meta:
+               app_label = 'philo'
+
+
+# the following line enables the selection of a node as the root for a given django.contrib.sites Site object
+models.ForeignKey(Node, related_name='sites', null=True, blank=True).contribute_to_class(Site, 'root_node')
+
+
+class Contentlet(models.Model):
+       page = models.ForeignKey(Page, related_name='contentlets')
+       name = models.CharField(max_length=255)
+       content = models.TextField()
+       dynamic = models.BooleanField(default=False)
+       
+       def __unicode__(self):
+               return self.name
+       
+       class Meta:
+               app_label = 'philo'
+
+
+class ContentReference(models.Model):
+       page = models.ForeignKey(Page, related_name='contentreferences')
+       name = models.CharField(max_length=255)
+       content_type = models.ForeignKey(ContentType, verbose_name='Content type')
+       content_id = models.PositiveIntegerField(verbose_name='Content ID', blank=True, null=True)
+       content = generic.GenericForeignKey('content_type', 'content_id')
+       
+       def __unicode__(self):
+               return self.name
+       
+       class Meta:
+               app_label = 'philo'
+
+
+register_templatetags('philo.templatetags.containers')
+
+
+register_value_model(Template)
+register_value_model(Page)
\ No newline at end of file