Source code for dynamite.models

from django.db import models
from django.db.models import signals
from dynamite import fields, handlers, registry

[docs]class AbstractSchema(models.Model): """This abstract model represents the Tables container (As a Database). You should inherit from this class when you want to start a dynamical model system. :: from dynamite.models import AbstractSchema from dynamite.registry import register class Survey(AbstractSchema): class Meta: verbose_name = 'survey' verbose_name_plural = 'surveys' .. note:: To activate this schema remember to register it in `yourapp.models` with: :: register( schema = Survey, ) """ name = models.CharField(max_length = 255) slug = models.SlugField(unique = True) _super_entity = NotImplemented _attribute = NotImplemented class Meta: abstract = True ordering = ('name',) def __unicode__(self): return self.name @classmethod def bind(cls, entity_cls, attribute_cls): cls._super_entity = entity_cls or AbstractEntity cls._attribute = attribute_cls or AbstractAttribute.factory(cls) cls._attribute._meta.unique_together = list(cls._attribute._meta.unique_together) cls._meta.ordering = cls._meta.ordering or AbstractSchema.Meta.ordering for ut in AbstractAttribute.Meta.unique_together: if ut not in cls._attribute._meta.unique_together: cls._attribute._meta.unique_together.append(ut) signals.pre_save.connect( handlers.attribute_pre_save, sender=cls._attribute ) signals.post_save.connect( handlers.attribute_post_save, sender=cls._attribute ) signals.pre_delete.connect( handlers.attribute_pre_delete, sender=cls._attribute ) signals.post_delete.connect( handlers.attribute_post_delete, sender=cls._attribute ) signals.post_save.connect( handlers.schema_post_save, sender=cls ) signals.post_delete.connect( handlers.schema_post_delete, sender=cls ) @property def entity(self): return self.get_entity() def get_entity(self, regenerate=False): name = self.slug.replace('-', '_').encode('ascii', 'ignore') app_name = self._super_entity._meta.app_label model_name = self._super_entity.__name__ + '_' +name cached_model = registry.cache.get(app_name, model_name, regenerate) if cached_model is not None: return cached_model attrs = { '__module__': getattr(self._super_entity, '__module__', __name__), } class Meta: app_label = app_name verbose_name = self.name.lower() + ' ' + unicode(self._super_entity._meta.verbose_name) attrs['Meta'] = Meta for attribute in getattr(self, self._attribute._meta.get_field('schema').related.get_accessor_name()).all(): field_name = attribute.slug.replace('-','_').encode('ascii', 'ignore') attrs[field_name] = attribute.get_field() model = type(model_name, (self._super_entity,), attrs) return model
[docs]class AbstractAttribute(models.Model): """This abstract model represents the table's fields template. You should inherit from this class when you want to add something to this template. :: from django.db import models from dynamite.models import AbstractSchema, AbstractAttribute from dynamite.registry import register class Survey(AbstractSchema): class Meta: verbose_name = 'survey' verbose_name_plural = 'surveys' .. note:: You have to make a foreign key through the schema: :: class Question(AbstractAttribute): rank = models.PositiveIntegerField(default=5) schema = models.ForeignKey(Survey) class Meta: ordering = ['rank'] verbose_name = 'question' verbose_name_plural = 'questions' .. note:: To activate this schema remember to register it in `yourapp.models` with: :: register( schema = Survey, attribute = Question, ) .. note:: At the moment an Attribute can be: * Short text * Long text * Number * Decimal number """ schema = NotImplemented name = models.CharField(max_length=255, default="") slug = models.SlugField() attr_type = models.CharField(max_length=32, choices=fields.ATTR_TYPES) choices = models.CharField(max_length=1024, default="", blank=True, help_text="comma separated choices, keep them shortish") required = models.BooleanField(default=False) def get_field(self): kwargs = { 'blank' : not self.required, 'verbose_name' : self.name, } if self.choices.strip(): kwargs['choices'] = [(x.strip(), x.strip()) for x in self.choices.split(",")] try: return fields.ATTR_FIELDS[self.attr_type](**kwargs) except KeyError: return None class Meta: abstract = True unique_together = (('schema', 'slug'),) @classmethod def factory(cls, schema): return type( 'Attribute', (cls,), dict( schema = models.ForeignKey(schema), __module__ = getattr(schema, '__module__'), ) )
[docs]class AbstractEntity(models.Model): """This abstract model represents the Table. You should inherit from this class when you want something in common in your schema. For example you want share uniqueness of primary keys :: from django.db import models from dynamite.models import AbstractSchema, AbstractEntity from dynamite.registry import register class Survey(AbstractSchema): class Meta: verbose_name = 'survey' verbose_name_plural = 'surveys' class Response(AbstractEntity): name = models.CharFields(primary_key = True) class Meta: abstract = True verbose_name = 'response' verbose_name_plural = 'responses' .. note:: To activate this schema remember to register it in `yourapp.models` with: :: register( schema = Survey, entity = Response, ) """ class Meta: abstract = True