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
-~----------~----~----~----~------~----~------~--~---