added boxes app

This commit is contained in:
Sanj 2011-04-04 07:05:25 +05:30
parent 5a7a6a99b6
commit 038aabbb7e
7 changed files with 294 additions and 51 deletions

View File

@ -1,6 +1,8 @@
'''
from django.contrib import admin from django.contrib import admin
from models import ModelBox, ModelSort, ModelExtraButton from models import ModelBox, ModelSort, ModelExtraButton
class ButtonsInline(admin.StackedInline): class ButtonsInline(admin.StackedInline):
model = ModelExtraButton model = ModelExtraButton
extra = 2 extra = 2
@ -13,3 +15,4 @@ class ModelBoxAdmin(admin.ModelAdmin):
admin.site.register(ModelBox, ModelBoxAdmin) admin.site.register(ModelBox, ModelBoxAdmin)
admin.site.register(ModelSort) admin.site.register(ModelSort)
admin.site.register(ModelExtraButton) admin.site.register(ModelExtraButton)
'''

View File

@ -4,7 +4,7 @@ from django.db.models import Q
from ox.text import smartSplit from ox.text import smartSplit
from ox.django.fields import DictField from ox.django.fields import DictField
from django.core.paginator import Paginator, InvalidPage, EmptyPage from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.contrib.contenttypes.models import ContentType
def splitSearch(string): def splitSearch(string):
ret = [] ret = []
@ -16,10 +16,11 @@ def splitSearch(string):
class ItfModel(models.Model): class ItfModel(models.Model):
fts_fields = [] fts_fields = []
fk_filters = [] fk_filters = []
related_models = [] # related_models = []
sort_fields = [] sort_fields = []
hasComments = True hasComments = True
class Meta: class Meta:
abstract = True abstract = True
@ -30,7 +31,7 @@ class ItfModel(models.Model):
return self.get_dict() return self.get_dict()
def get_dict(self): def get_dict(self):
return self.get(self._get_fields().keys() + self.related_models) return self.get(self._get_fields().keys())
def get(self, props): def get(self, props):
typ = type(props) typ = type(props)
@ -167,8 +168,9 @@ class ItfModel(models.Model):
operator = '-' operator = '-'
else: else:
operator = '' operator = ''
sort = operator + s['key'] sort = operator + s['ey']
qset = qset.order_by(sort) qset = qset.order_by(sort)
r0 = options['range'][0] r0 = options['range'][0]
r1 = options['range'][1] r1 = options['range'][1]
results = qset[r0:r1] results = qset[r0:r1]
@ -185,53 +187,6 @@ def getField(fields, name):
class ModelBox(models.Model):
model = models.ForeignKey(ContentType)
friendly_name = models.CharField(max_length=256)
friendly_name_singular = models.CharField(max_length=256, blank=True, null=True)
info = models.TextField(blank=True)
sort_options = models.ManyToManyField("ModelSort", blank=True, null=True)
# filter_fields = DictField(blank=True)
is_visible = models.BooleanField(default=True)
@property
def module(self):
return self.model.app_label
def __unicode__(self):
return self.friendly_name
def get_dict(self):
# sort_options = map(lambda x: {'key': x.key, 'text': x.text}, self.sort_options.all())
return {
'module': self.module,
'model': self.model.model,
'info': self.info,
'friendly_name': self.friendly_name,
'friendly_name_singular': self.friendly_name_singular,
'fk_filters': self.model.model_class().fk_filters,
'fts_fields': self.model.model_class().fts_fields,
'sort_options': map(lambda x: {'key': x.key, 'text': x.text}, self.sort_options.all())
}
class ModelSort(models.Model):
key = models.CharField(max_length=64)
text = models.CharField(max_length=512)
def __unicode__(self):
return "%s: %s" % (self.key, self.text,)
class ModelExtraButton(models.Model):
icon = models.CharField(max_length=64)
mouseover = models.CharField(max_length=512, blank=True, null=True)
dialog_text = models.TextField()
model = models.ForeignKey(ModelBox)
def __unicode__(self):
return self.mouseover
def site_config(): def site_config():
with open(settings.SITE_CONFIG) as f: with open(settings.SITE_CONFIG) as f:
site_config = json.load(f) site_config = json.load(f)

0
itf/boxes/__init__.py Normal file
View File

226
itf/boxes/models.py Normal file
View File

@ -0,0 +1,226 @@
from django.db import models
from django.contrib.contenttypes.models import ContentType
from app.models import ItfModel
from django.contrib.contenttypes import generic
'''
Classes that need to link to a ContentType should link to ModelExtra instead. Maybe there's a better way to do this?
'''
class ModelExtra(models.Model):
model = models.OneToOneField(ContentType)
friendly_name = models.CharField(max_length=255, blank=True, null=True)
friendly_name_plural = models.CharField(max_length=255, blank=True, null=True)
sort_options = models.ManyToManyField("ModelSort", blank=True, null=True)
def __unicode__(self):
return "%d: %s" % (self.id, self.friendly_name)
def get_dict(self):
return {
'module': self.model.model_class()._meta.app_label,
'model': self.model.model,
# 'info': self.info,
'friendly_name': self.friendly_name,
'friendly_name_plural': self.friendly_name_plural,
'fk_filters': self.model.model_class().fk_filters,
'fts_fields': self.model.model_class().fts_fields,
'sort_options': map(lambda x: {'key': x.key, 'text': x.text}, self.sort_options.all())
}
class ModelSort(models.Model):
key = models.CharField(max_length=64)
text = models.CharField(max_length=512)
def __unicode__(self):
return "%s: %s" % (self.key, self.text,)
"""
Base class for buttons - buttons can be an 'extra_button' for either a Box class or an instance of a model (defined in ModelExtra).
"""
class Button(ItfModel):
typ = ''
icon = models.CharField(max_length=255) #FIXME: read choices from list of icons
mouseover = models.CharField(max_length=255)
class Meta:
abstract = True
def __unicode__(self):
return "%d: %s" % (self.id, self.mouseover)
def get_dict(self):
data = self.get_data()
data['type'] = self.typ,
data['icon'] = self.icon,
data['mouseover'] = self.mouseover
return data
'''
Subclasses need to implement get_data and return additional data-items as a dict. Keys cannot be one of 'type', 'icon', and 'mouseover' in the return value.
'''
def get_data(self):
return {}
class BoxButton(Button):
class Meta:
abstract = True
class ModelButton(Button):
class Meta:
abstract = True
class DialogButton(BoxButton):
typ = 'dialog'
dialogTitle = models.CharField(max_length=255)
dialogHTML = models.TextField()
def get_data(self):
return {
'title': self.dialogTitle,
'html': self.dialogHTML
}
class StaticDownloadButton(BoxButton):
typ = 'staticDownload'
fil = models.FileField(upload_to='uploads/button_downloads/')
def get_data(self):
return {
'file': {
'path': self.fil.url
}
}
class ModelDownloadButton(ModelButton):
typ = 'modelDownload'
file_field = models.CharField(max_length=100) #name of field which holds the file/s(?) to be downloaded
def get_data(self):
return {
'file': {
'path': self.fil.url
}
}
"""
Join model to enable m2m relations to generic foreign keys
"""
class ExtraButton(models.Model):
related_name = models.CharField(max_length=255, blank=True, null=True)
button_content_type = models.ForeignKey(ContentType)
button_id = models.PositiveIntegerField()
button = generic.GenericForeignKey('button_content_type', 'button_id')
def __unicode__(self):
return "%d: %s" % (self.id, self.related_name)
def get_dict(self):
return self.button.get_dict()
"""
Join model
"""
class PanelBoxes(models.Model):
related_name = models.CharField(max_length=255, blank=True, null=True)
box_content_type = models.ForeignKey(ContentType)
box_id = models.PositiveIntegerField()
box = generic.GenericForeignKey("box_content_type", "box_id")
def __unicode__(self):
return "%d: %s" % (self.id, self.related_name)
def get_dict(self):
return self.box.get_dict()
class Meta:
verbose_name = "Panel box"
verbose_name_plural = "Panel boxes"
'''
Abstract base-class for boxes.
'''
class Box(ItfModel):
title = models.CharField(max_length=256)
extra_buttons = models.ManyToManyField("ExtraButton", blank=True, null=True)
class Meta:
abstract = True
def render():
return ''
def __unicode__(self):
return "%d: %s" % (self.id, self.title)
def _get_buttons(self):
ret = []
for b in self.extra_buttons.all():
ret.append(b.button.get_dict())
return ret
def get_dict(self):
return {}
class StaticBox(Box):
html = models.TextField(blank=True, null=True)
def get_dict(self):
return {
'type': 'StaticBox',
'title': self.title,
'html': self.html,
'extra_buttons': self._get_buttons()
}
class ModelsBox(Box):
default_model = models.ForeignKey(ModelExtra)
view_models = models.ManyToManyField(ModelExtra, related_name="box_views", blank=True, null=True)
info = models.TextField(blank=True)
@property
def module(self):
return self.default_model.app_label
def get_dict(self):
data = {
'type': 'ModelsBox',
'title': self.title,
'info': self.info,
'extra_buttons': self._get_buttons(),
'default_model': self.default_model.get_dict(),
'view_models': map(lambda x: x.get_dict(), self.view_models.all())
}
return data
class Panel(models.Model):
title = models.CharField(max_length=255)
boxes = models.ManyToManyField("PanelBoxes", blank=True, null=True)
enabled = models.BooleanField(default=False)
displayed = models.BooleanField(default=False)
def __unicode__(self):
return self.title
def get_dict(self):
return {
'title': self.title,
'boxes': map(lambda x: x.get_dict(), self.boxes.all())
}

23
itf/boxes/tests.py Normal file
View File

@ -0,0 +1,23 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

35
itf/boxes/views.py Normal file
View File

@ -0,0 +1,35 @@
# Create your views here.
from api.actions import actions
import ox
from ox.django.decorators import login_required_json
from ox.django.shortcuts import render_to_json_response, get_object_or_404_json, json_response
from models import Panel
def getPage(request):
'''
returns displayed panels as displayed; hidden panels as hidden.
each panel is:
title
boxes:
type
title
default_model
etc
'''
data = json.loads(request.POST['data'])
displayedPanels = Panel.objects.filter(enabled=True).filter(displayed=True)
hiddenPanels = Panel.objects.filter(enabled=True).filter(displayed=False)
panels = {}
panels['displayed'] = []
for d in displayedPanels:
panels['displayed'].append(d.get_dict())
panels['hidden'] = []
for h in hiddenPanels:
panels['hidden'].append(h.get_dict())
response = json_response({})
response['data'] = panels
response['status'] = {'code': 200}
return render_to_json_response(response)
actions.register(getPage)

View File

@ -141,6 +141,7 @@ INSTALLED_APPS = (
'tagging', 'tagging',
'app', 'app',
'api', 'api',
'boxes',
# 'solango', # 'solango',
'multilingual', 'multilingual',
# 'multilingual.flatpages', # 'multilingual.flatpages',