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) has_comments = models.BooleanField(default=False) def __unicode__(self): return "%d: %s" % (self.id, self.friendly_name) def get_dict(self): return { 'id': self.id, 'module': self.model.model_class()._meta.app_label, 'model': self.model.model_class().__name__, 'has_comments': self.has_comments, # '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, 'operator': x.operator, 'text': x.text}, self.sort_options.all()) } class ModelSort(models.Model): operator = models.CharField(max_length=4) key = models.CharField(max_length=64) text = models.CharField(max_length=256) def __unicode__(self): return "%s%s: %s" % (self.operator, 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['id'] = self.id, 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) logo = models.ImageField(upload_to="upload/box_logos/", 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 { 'id': self.id, '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 = { 'id': self.id, '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 { 'id': self.id, 'title': self.title, 'boxes': map(lambda x: x.get_dict(), self.boxes.all()) } ''' class Page(models.Model): class Meta: abstract = True '''