Author: floguy
Date: Sat Oct  4 20:30:19 2008
New Revision: 42

Added:
    trunk/things/templates/things/groups.html
Modified:
    trunk/things/__init__.py
    trunk/things/fields.py
    trunk/things/options.py
    trunk/things/templates/things/list.html
    trunk/thingsproject/dev.db
    trunk/thingsproject/settings.py
    trunk/thingsproject/twitter/thing.py
    trunk/thingsproject/urls.py

Log:
Added the ability to group domain objects into arbitrary different  
querysets.

Modified: trunk/things/__init__.py
==============================================================================
--- trunk/things/__init__.py    (original)
+++ trunk/things/__init__.py    Sat Oct  4 20:30:19 2008
@@ -1,7 +1,6 @@
-from things.options import ModelThing, BaseThing
+from things.options import *
+from things.fields import *
  from things.sites import ThingSite, site
-from things.fields import OrderField, OrderCountField,  
OrderGenericCountField
-from things.fields import OrderSumField, OrderGenericSumField

  def autodiscover():
      """

Modified: trunk/things/fields.py
==============================================================================
--- trunk/things/fields.py      (original)
+++ trunk/things/fields.py      Sat Oct  4 20:30:19 2008
@@ -5,7 +5,9 @@
  from django.db import connection
  from django.contrib.contenttypes.models import ContentType

-__all__ = ('OrderField', )
+__all__ =  
('OrderField', 'ForeignKeyAggregate', 'GenericForeignKeyAggregate',
+    'OrderSumField', 'OrderCountField', 'OrderGenericCountField',
+    'OrderGenericSumField')

  qn = connection.ops.quote_name

@@ -82,7 +84,7 @@
                  'url_prefix': self.parent.url_prefix,
          })

-class AggregateBase(object):
+class AggregateBase(BaseField):
      def get_aggregate_name(self):
          raise NotImplementedError


Modified: trunk/things/options.py
==============================================================================
--- trunk/things/options.py     (original)
+++ trunk/things/options.py     Sat Oct  4 20:30:19 2008
@@ -1,4 +1,5 @@
  import re
+import copy
  from operator import or_
  from django.conf.urls.defaults import *
  from django.http import HttpResponse, Http404
@@ -8,6 +9,9 @@
  from django.core.urlresolvers import reverse
  from django.db.models import Q
  from things.fields import BaseField, OrderCountField, AggregateBase
+from django.template import defaultfilters
+
+__all__ = ('Thing', 'ModelThing', 'ThingGroup')

  class BaseThingMetaclass(type):
      def __new__(cls, name, bases, attrs):
@@ -18,10 +22,9 @@
          attrs['fields'] = fields
          new_class = super(BaseThingMetaclass, cls).__new__(cls, name,  
bases,
              attrs)
-        new_class.qs = property(new_class.get_query_set)
          return new_class

-class BaseThing(object):
+class Thing(object):
      __metaclass__ = BaseThingMetaclass

      fields = {}
@@ -30,21 +33,27 @@
      template_dir = 'things'
      search = []

-    def __init__(self):
-        for (name, field) in self.fields.iteritems():
+    def __init__(self, qs):
+        self.qs = qs
+        self.model = qs.model
+        self.opts = self.model._meta
+        fields = copy.deepcopy(self.fields)
+        for (name, field) in fields.iteritems():
              assert isinstance(field, BaseField) == True
              field.parent = self
              field.field_name = name
+        self.fields = fields
          if not self.detail_template_name:
              self.detail_template_name = '%s_detail.html' %  
self.opts.module_name
          if not self.list_template_name:
              self.list_template_name = '%s_list.html' %  
self.opts.module_name

      def list_view(self, request, descending=False, field=None,
-        template_object_name='objects', template_name=None, **kwargs):
+        template_object_name='objects', template_name=None,
+        extra_context = {}, **kwargs):
          if template_name is None:
              template_name = self.list_template_name
-        items = self.qs
+        items = self.get_query_set()
          terms = request.REQUEST.get('search', '')
          if terms and bool(self.search):
              kwargs = {}
@@ -73,8 +82,7 @@
                  items = items.order_by('%s%s' % (pre, field.field_name))
          templates = ['%s/%s' % (self.template_dir, template_name,),
              '%s/list.html' % self.template_dir, 'things/list.html']
-        t = select_template(templates)
-        c = RequestContext(request, {
+        context = {
              template_object_name: items,
              'fields': self.fields.values(),
              'field': field,
@@ -83,15 +91,18 @@
              'name_prefix': self.name_prefix,
              'search_enabled': bool(self.search),
              'terms': terms,
-        })
+        }
+        context.update(extra_context)
+        t = select_template(templates)
+        c = RequestContext(request, context)
          return HttpResponse(t.render(c))

      def detail_view(self, request, pk, template_object_name='object',
-        template_name=None, url_prefix=None):
+        template_name=None, url_prefix=None, extra_context={}):
          if template_name is None:
              template_name = self.detail_template_name
          try:
-            obj = self.qs.get(pk=pk)
+            obj = self.get_query_set().get(pk=pk)
          except self.model.DoesNotExist:
              raise Http404
          list_url = reverse('%s_list' % (self.name_prefix,), kwargs={
@@ -99,14 +110,17 @@
          })
          templates = ['%s/%s' % (self.template_dir, template_name,),
              '%s/detail.html' % self.template_dir, 'things/detail.html']
-        t = select_template(templates)
-        c = RequestContext(request, {
+        context = {
              template_object_name: obj,
              'list_url': list_url,
-        })
+        }
+        context.update(extra_context)
+        t = select_template(templates)
+        c = RequestContext(request, context)
          return HttpResponse(t.render(c))

-    def urls(self, prefix='^', name_prefix=None, url_prefix=None):
+    def urls(self, prefix='^', name_prefix='things', url_prefix='',
+        extra_context={}):
          self.name_prefix = name_prefix # Is this robust enough? Needs  
testing.
          self.url_prefix = url_prefix
          if self.url_prefix is None:
@@ -114,17 +128,24 @@
                  self.opts.module_name)
          tmp_urls = [
              url(r'%s(?P<url_prefix>%s)$' % (prefix, self.url_prefix),
-                self.list_view, name='%s_list' % name_prefix),
+                self.list_view,
+                {'extra_context': extra_context},
+                name='%s_list' % name_prefix),
              url(r'%s(?P<url_prefix>%s)detail/(?P<pk>\d+)/$' % (prefix,
                  self.url_prefix),
-                self.detail_view, name='%s_detail' % name_prefix)
+                self.detail_view,
+                {'extra_context': extra_context},
+                name='%s_detail' % name_prefix)
          ]
          tmp_urls.extend([
              url('%s(?P<url_prefix>%s)order/%s/%s/' % (prefix,  
self.url_prefix,
                  field.field_url, field.url_asc),
                  self.list_view,
-                {'descending': False,
-                 'field': self.fields.get(field.field_name, None),},
+                {
+                    'descending': False,
+                    'field': self.fields.get(field.field_name, None),
+                    'extra_context': extra_context,
+                },
                  name='%s_%s_list_asc' % (name_prefix, field.field_url))
              for (name, field) in self.fields.iteritems()
          ])
@@ -132,23 +153,100 @@
              url('%s(?P<url_prefix>%s)order/%s/%s/' % (prefix,  
self.url_prefix,
              field.field_url, field.url_desc),
                  self.list_view,
-                {'descending': True,
-                 'field': self.fields.get(field.field_name, None)},
+                {
+                    'descending': True,
+                    'field': self.fields.get(field.field_name, None),
+                    'extra_context': extra_context,
+                },
                  name='%s_%s_list_desc' % (name_prefix, field.field_url))
              for (name, field) in self.fields.iteritems()
          ])
          return patterns('', *tmp_urls)

      def get_query_set(self):
-        query_set = self.model._default_manager.all()
+        query_set = self.qs
          for field_name, field in self.fields.iteritems():
              if isinstance(field, AggregateBase):
                  query_set = field.modify_query_set(query_set)
          return query_set

-class ModelThing(BaseThing):
+class ModelThing(Thing):
      def __init__(self, model):
-        self.model = model
-        self.opts = model._meta
-        super(ModelThing, self).__init__()
-
\ No newline at end of file
+        qs = model._default_manager.all()
+        super(ModelThing, self).__init__(qs)
+
+class ThingGroup(object):
+    """
+    [
+        {
+            'queryset': MyModel.objects.filter(name='asdf'),
+            'name': 'my_name',
+            'url_name': 'my_url_name',
+            'description': 'my_description',
+        },
+    ]
+    """
+    template_name = None
+    template_dir = 'things'
+
+    def __init__(self, thing, group_dicts=None, group_func=None):
+        if group_dicts is not None and group_func is not None:
+            raise TypeError("Both group_dicts and group_func cannot be  
specified.")
+        if not group_dicts and not group_func:
+            raise TypeError("Either group_dicts or group_func must be  
specified.")
+        if group_dicts:
+            self.groups = group_dicts
+        else:
+            self.groups = group_func(thing)
+        for group in self.groups:
+            for key in ('queryset', 'name', 'url_name'):
+                if key not in group:
+                    raise TypeError("Group dictionary must include a '%s'  
argument." % key)
+        self.thing = thing
+
+    def urls(self, prefix='^', name_prefix='things', url_prefix='',
+        extra_context={}):
+        self.name_prefix = name_prefix # Is this robust enough? Needs  
testing.
+        self.prefix = prefix
+        self.url_prefix = url_prefix
+        tmp_urls = [
+            url(
+                r'%s(?P<url_prefix>%s)$' % (prefix, self.url_prefix),
+                self.group_view,
+                {'extra_context': extra_context},
+                name='%s_group_list' % name_prefix),
+        ]
+        for group in self.groups:
+            thing = self.thing(qs=group['queryset'])
+            description = group.get('description', '')
+            context = {
+                'group_name': group['name'],
+                'group_description': description,
+                'groups': self.groups,
+            }
+            context.update(extra_context)
+            tmp_urls.extend(thing.urls(
+                prefix='%s%s' % (prefix, self.url_prefix, ),
+                extra_context=context,
+                name_prefix="%s_%s" % (name_prefix, group['url_name']),
+                url_prefix='%s/' % group['url_name'],
+            ))
+        return patterns('', *tmp_urls)
+
+    def group_view(self, request, extra_context={}, url_prefix=None):
+        if self.template_name is None:
+            template_name = '%s_groups.html' % (self.__class__.__name__,)
+        else:
+            template_name = self.template_name
+        templates = ['%s/%s' % (self.template_dir, template_name,),
+            '%s/groups.html' % self.template_dir, 'things/groups.html']
+        groups = self.groups
+        for group in groups:
+            group['url'] = reverse('%s_%s_list' % (self.name_prefix,  
group['url_name']), kwargs={'url_prefix': '%s/' % group['url_name']})
+        context = {
+            'groups': groups,
+        }
+        context.update(extra_context)
+        t = select_template(templates)
+        c = RequestContext(request, context)
+        return HttpResponse(t.render(c))
\ No newline at end of file

Added: trunk/things/templates/things/groups.html
==============================================================================
--- (empty file)
+++ trunk/things/templates/things/groups.html   Sat Oct  4 20:30:19 2008
@@ -0,0 +1,10 @@
+{% extends "things/base.html" %}
+
+{% block main_content %}
+    <p>Groups:</p>
+    <ul>
+        {% for group in groups %}
+            <li><a href="{{ group.url }}">{{ group.name }}</a></li>
+        {% endfor %}
+    </ul>
+{% endblock %}
\ No newline at end of file

Modified: trunk/things/templates/things/list.html
==============================================================================
--- trunk/things/templates/things/list.html     (original)
+++ trunk/things/templates/things/list.html     Sat Oct  4 20:30:19 2008
@@ -5,6 +5,7 @@
      <p>Order By:</p>
      {% display_search %}
      {% display_ordering %}
+    {% if group_name %}<p>{{ group_name }}</p>{% endif %}
      <ul>
          {% for item in objects %}
              <li><a href="{% item_url url_prefix name_prefix item %}">{{  
item }}</a></li>

Modified: trunk/thingsproject/dev.db
==============================================================================
Binary files. No diff available.

Modified: trunk/thingsproject/settings.py
==============================================================================
--- trunk/thingsproject/settings.py     (original)
+++ trunk/thingsproject/settings.py     Sat Oct  4 20:30:19 2008
@@ -64,6 +64,14 @@
      'django.middleware.doc.XViewMiddleware',
  )

+TEMPLATE_CONTEXT_PROCESSORS = (
+    "django.core.context_processors.auth",
+    "django.core.context_processors.debug",
+    "django.core.context_processors.i18n",
+    "django.core.context_processors.media",
+    "django.core.context_processors.request",
+)
+
  ROOT_URLCONF = 'thingsproject.urls'

  TEMPLATE_DIRS = (

Modified: trunk/thingsproject/twitter/thing.py
==============================================================================
--- trunk/thingsproject/twitter/thing.py        (original)
+++ trunk/thingsproject/twitter/thing.py        Sat Oct  4 20:30:19 2008
@@ -1,12 +1,27 @@
+import datetime
  import things
  from models import Tweet

-class TweetThing(things.ModelThing):
+class TweetThing(things.Thing):
      date_posted = things.OrderField(verbose_name_asc='Newest',
          verbose_name_desc='Oldest', url_asc='newest', url_desc='oldest',
          field_url='date')
      vote_set = things.OrderSumField('value')
      message = things.OrderField()
      search = ('message', 'date_posted')
+
+yesterday = datetime.datetime.today() - datetime.timedelta(days=1)
+group_dicts = [
+    {
+        'queryset': Tweet.objects.filter(date_posted__lte=yesterday),
+        'name': 'Tweets Yesterday',
+        'url_name': 'yesterday',
+    },
+    {
+        'queryset': Tweet.objects.filter(date_posted__gt=yesterday),
+        'name': 'Tweets Today',
+        'url_name': 'today',
+    },
+]

  #things.site.register(Tweet, TweetThing)

Modified: trunk/thingsproject/urls.py
==============================================================================
--- trunk/thingsproject/urls.py (original)
+++ trunk/thingsproject/urls.py Sat Oct  4 20:30:19 2008
@@ -5,11 +5,11 @@
  admin.autodiscover()
  #things.autodiscover()

-from twitter.thing import TweetThing
+from twitter.thing import TweetThing, group_dicts
  from twitter.models import Tweet

-tt = TweetThing(Tweet)
+thing = things.ThingGroup(TweetThing, group_dicts=group_dicts)

  urlpatterns = patterns('',
       (r'^admin/(.*)$', admin.site.root),
-) + tt.urls(url_prefix='tweets/')
\ No newline at end of file
+) + thing.urls()
\ No newline at end of file

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pinax-updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pinax-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to