added boxes app
This commit is contained in:
parent
5a7a6a99b6
commit
038aabbb7e
|
@ -1,6 +1,8 @@
|
|||
'''
|
||||
from django.contrib import admin
|
||||
from models import ModelBox, ModelSort, ModelExtraButton
|
||||
|
||||
|
||||
class ButtonsInline(admin.StackedInline):
|
||||
model = ModelExtraButton
|
||||
extra = 2
|
||||
|
@ -13,3 +15,4 @@ class ModelBoxAdmin(admin.ModelAdmin):
|
|||
admin.site.register(ModelBox, ModelBoxAdmin)
|
||||
admin.site.register(ModelSort)
|
||||
admin.site.register(ModelExtraButton)
|
||||
'''
|
||||
|
|
|
@ -4,7 +4,7 @@ from django.db.models import Q
|
|||
from ox.text import smartSplit
|
||||
from ox.django.fields import DictField
|
||||
from django.core.paginator import Paginator, InvalidPage, EmptyPage
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
|
||||
def splitSearch(string):
|
||||
ret = []
|
||||
|
@ -16,10 +16,11 @@ def splitSearch(string):
|
|||
class ItfModel(models.Model):
|
||||
fts_fields = []
|
||||
fk_filters = []
|
||||
related_models = []
|
||||
# related_models = []
|
||||
sort_fields = []
|
||||
hasComments = True
|
||||
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
@ -30,7 +31,7 @@ class ItfModel(models.Model):
|
|||
return self.get_dict()
|
||||
|
||||
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):
|
||||
typ = type(props)
|
||||
|
@ -167,8 +168,9 @@ class ItfModel(models.Model):
|
|||
operator = '-'
|
||||
else:
|
||||
operator = ''
|
||||
sort = operator + s['key']
|
||||
sort = operator + s['ey']
|
||||
qset = qset.order_by(sort)
|
||||
|
||||
r0 = options['range'][0]
|
||||
r1 = options['range'][1]
|
||||
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():
|
||||
with open(settings.SITE_CONFIG) as f:
|
||||
site_config = json.load(f)
|
||||
|
|
0
itf/boxes/__init__.py
Normal file
0
itf/boxes/__init__.py
Normal file
226
itf/boxes/models.py
Normal file
226
itf/boxes/models.py
Normal 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
23
itf/boxes/tests.py
Normal 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
35
itf/boxes/views.py
Normal 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)
|
|
@ -141,6 +141,7 @@ INSTALLED_APPS = (
|
|||
'tagging',
|
||||
'app',
|
||||
'api',
|
||||
'boxes',
|
||||
# 'solango',
|
||||
'multilingual',
|
||||
# 'multilingual.flatpages',
|
||||
|
|
Loading…
Reference in New Issue
Block a user