Implementation of a Node class, the subclasses of which respond to requests at differ...
authorJoseph Spiros <joseph.spiros@ithinksw.com>
Mon, 8 Mar 2010 00:26:14 +0000 (19:26 -0500)
committerJoseph Spiros <joseph.spiros@ithinksw.com>
Mon, 8 Mar 2010 00:32:39 +0000 (19:32 -0500)
Also, removed the requirement on django-mptt, as currently none of its features are needed, and I have yet to figure out how to make it work in multi-table inheritance situations.

README
admin.py
models.py
urls.py
views.py

diff --git a/README b/README
index 81a59cd..82333d6 100644 (file)
--- a/README
+++ b/README
@@ -4,7 +4,6 @@ Prerequisites:
        * Python 2.5.4+ <http://www.python.org/>
        * simplejson <http://code.google.com/p/simplejson/> (Not required with Python 2.6+)
        * Django 1.1.1+ <http://www.djangoproject.com/>
-       * django-mptt 0.2+ <http://code.google.com/p/django-mptt/>
        * (Optional) django-grappelli 2.0+ <http://code.google.com/p/django-grappelli/>
 
 To contribute, please visit the project website <http://philo.ithinksw.org/>.
index 229e16d..faf4b71 100644 (file)
--- a/admin.py
+++ b/admin.py
@@ -126,5 +126,7 @@ class PageAdmin(EntityAdmin):
 
 
 admin.site.register(Collection, CollectionAdmin)
+admin.site.register(Redirect)
+admin.site.register(File)
 admin.site.register(Page, PageAdmin)
 admin.site.register(Template, TemplateAdmin)
index 3a06d0a..4eb50f7 100644 (file)
--- a/models.py
+++ b/models.py
@@ -5,12 +5,11 @@ 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
-import mptt
 from 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
+from django.template import Context, RequestContext
 from django.core.exceptions import ObjectDoesNotExist
 try:
        import json
@@ -20,6 +19,8 @@ from UserDict import DictMixin
 from templatetags.containers import ContainerNode
 from django.template.loader_tags import ExtendsNode, ConstantIncludeNode, IncludeNode
 from django.template.loader import get_template
+from django.http import HttpResponse, HttpResponseServerError, HttpResponseRedirect
+from django.core.servers.basehttp import FileWrapper
 
 
 def _ct_model_name(model):
@@ -214,6 +215,50 @@ class TreeEntity(TreeModel, Entity):
                abstract = True
 
 
+class Node(TreeEntity):
+       instance_type = models.ForeignKey(ContentType, editable=False)
+       
+       def save(self, force_insert=False, force_update=False):
+               if not hasattr(self, 'instance_type_ptr'):
+                       self.instance_type = ContentType.objects.get_for_model(self.__class__)
+               super(Node, self).save(force_insert, force_update)
+       
+       @property
+       def instance(self):
+               return self.instance_type.get_object_for_this_type(id=self.id)
+       
+       accepts_subpath = False
+       
+       def render_to_response(self, request, path=None, subpath=None):
+               return HttpResponseServerError()
+
+
+class Redirect(Node):
+       STATUS_CODES = (
+               (302, 'Temporary'),
+               (301, 'Permanent'),
+       )
+       target = models.URLField()
+       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 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 Template(TreeModel):
        name = models.CharField(max_length=255)
        documentation = models.TextField(null=True, blank=True)
@@ -274,20 +319,21 @@ class Template(TreeModel):
                except Template.DoesNotExist:
                        raise TemplateDoesNotExist(template_name)
                return (template.code, template.origin)
-mptt.register(Template)
 
 
-class Page(TreeEntity):
+class Page(Node):
        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')
-mptt.register(Page)
 
 
-# the following line enables the selection of a page as the root for a given django.contrib.sites Site object
-models.ForeignKey(Page, related_name='sites', null=True, blank=True).contribute_to_class(Site, 'root_page')
+# 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):
diff --git a/urls.py b/urls.py
index 77ec968..c4fcb5e 100644 (file)
--- a/urls.py
+++ b/urls.py
@@ -1,8 +1,8 @@
 from django.conf.urls.defaults import url, include, patterns, handler404, handler500
-from philo.views import page_view
+from philo.views import node_view
 
 
 urlpatterns = patterns('',
-       url(r'^$', page_view, name='philo-root'),
-       url(r'^(?P<path>.*)$', page_view, name='philo-page-by-path')
+       url(r'^$', node_view, name='philo-root'),
+       url(r'^(?P<path>.*)$', node_view, name='philo-node-by-path')
 )
index 65acb52..5e4b7dd 100644 (file)
--- a/views.py
+++ b/views.py
@@ -1,18 +1,19 @@
 from django.http import Http404, HttpResponse
 from django.template import RequestContext
 from django.contrib.sites.models import Site
-from models import Page
+from models import Node
 
-def page_view(request, path=None, **kwargs):
-       page = None
+
+def node_view(request, path=None, **kwargs):
+       node = None
        if path is None:
                path = '/'
        try:
                current_site = Site.objects.get_current()
                if current_site:
-                       page = Page.objects.get_with_path(path, root=current_site.root_page)
-       except Page.DoesNotExist:
+                       node = Node.objects.get_with_path(path, root=current_site.root_node)
+       except Node.DoesNotExist:
                raise Http404
-       if not page:
+       if not node:
                raise Http404
-       return HttpResponse(page.template.django_template.render(RequestContext(request, {'page': page})), mimetype=page.template.mimetype)
+       return node.instance.render_to_response(request, path=path)