"""
Jumbo models
=============
Per semplificare la creazione di modelli dove il pattern viene ripetuto
spesso, Jumbo fornisce i seguenti modelli astratti:
.. autoclass:: DateModel
.. autoclass:: StatusModel
"""
import datetime
import os.path
import time
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
from jumbo.db.fields import *
from jumbo.db import HackForeignKey
[docs]class DateModel(models.Model):
"""
An abstract model that adds ``date_create`` and ``date_last_modify```
"""
class Meta:
abstract = True
date_create = models.DateTimeField(
verbose_name=_('date create'),
blank=True, null=True
)
date_last_modify = models.DateTimeField(
verbose_name=_('date last modify'),
blank=True, null=True
)
def save(self, *args, **kwargs):
now = datetime.datetime.now()
if not self.pk:
self.date_create = now
self.date_last_modify = now
super(DateModel, self).save(*args, **kwargs)
[docs]class StatusModel(models.Model):
"""
An abstract model that adds status as :class:`StatusField`
"""
class Meta:
abstract = True
status = StatusField()
class DefaultModel(models.Model):
class Meta:
abstract = True
default = models.BooleanField(
default=False,
verbose_name=_('Default'),
)
class OrderedModel(models.Model):
class Meta:
abstract = True
ordering = models.IntegerField(
verbose_name=_('ordering'),
)
def brothers_and_me(self):
return self._default_manager.all()
def brothers(self):
return self.brothers_and_me().exclude(pk=self.id)
def is_first(self):
return self.brothers_and_me().order_by('ordering')[0:1][0] == self
def is_last(self):
return self.brothers_and_me().order_by('-ordering')[0:1][0] == self
def _switch_node(self, other):
self.ordering, other.ordering = other.ordering, self.ordering
self.save()
other.save()
def up(self):
brothers = self.brothers().order_by('-ordering').filter(ordering__lt=self.ordering+1)[0:1]
if not brothers.count():
return False
if brothers[0].ordering == self.ordering:
self._set_default_ordering()
self.save()
self._switch_node(brothers[0])
return True
def down(self):
brothers = self.brothers().order_by('ordering').filter(ordering__gt=self.ordering-1)[0:1]
if not brothers.count():
return False
brother = brothers[0]
if brother.ordering == self.ordering:
brother._set_default_ordering()
brother.save()
self._switch_node(brother)
return True
def _set_default_ordering(self):
max = 0
brothers = self.brothers()
if brothers.count():
for brother in brothers:
if brother.ordering >= max:
max = brother.ordering
self.ordering = max + 1
def save(self, *args, **kwargs):
if not self.ordering:
try:
model = self.__class__
last_obj = model.objects.order_by('-ordering')[0:1].get()
new_ordering = last_obj.ordering + 10
except self.DoesNotExist:
new_ordering = 0
self.ordering = new_ordering
super(OrderedModel, self).save(*args, **kwargs)
class TreeOrderedModel(OrderedModel):
class Meta:
abstract = True
parent = models.ForeignKey(
'self',
db_index=True,
null=True,
blank=True,
related_name='children',
verbose_name=_('parent node'),
help_text=_('parent node'),
)
def brothers_and_me(self):
if self.parent:
return self._default_manager.filter(parent=self.parent)
else:
return self._default_manager.filter(parent__isnull=True)
class UserModel(models.Model):
class Meta:
abstract = True
creator = HackForeignKey(
User,
blank=True,
null=True,
db_index = True,
related_name = "%(app_label)s_%(class)s_creator",
verbose_name = _("creator"),
)
last_modifier = HackForeignKey(
User,
blank=True,
null=True,
db_index = True,
related_name = '%(app_label)s_%(class)s_last_modifier',
verbose_name = _("last modifier"),
)
def save(self, user=None, *args, **kwargs):
if not isinstance(user, User):
from jumbo.middleware.thread_local import get_current_user
user = get_current_user()
if isinstance(user, User):
if not self.id:
self.creator = user
self.last_modifier = user
super(UserModel, self).save(*args, **kwargs)
class DefaultModelManager(models.Manager):
def default(self):
return self.get_query_set().get(default=True)
class AssociatedUserModel(models.Model):
class Meta:
abstract = True
user = models.ForeignKey(
User,
verbose_name=_('user'),
help_text=_('user help text'),
)
CAT_PERIODICITY = (
("o", _("occasional"),),
('s', _("series"),),
("d", _("daily"),),
("w", _("weekly"),),
("m", _("monthly"),),
("y", _("yearly"),),
)
class PeriodicityModel(models.Model):
class Meta:
abstract = True
cat = models.CharField(
max_length = 1,
default = "o",
choices = CAT_PERIODICITY,
db_index = True,
verbose_name = _("type")
)
delivery_date = models.DateField(
blank = True, null = True,
db_index = True,
verbose_name = _("delivery date"),
)
mon = models.BooleanField(
db_index = True,
verbose_name = _('mon')
)
tue = models.BooleanField(
db_index = True,
verbose_name = _('tue')
)
wed = models.BooleanField(
db_index = True,
verbose_name = _('wed')
)
thu = models.BooleanField(
db_index = True,
verbose_name = _('thu')
)
fri = models.BooleanField(
db_index = True,
verbose_name = _('fri')
)
sat = models.BooleanField(
db_index = True,
verbose_name = _('sat')
)
sun = models.BooleanField(
db_index = True,
verbose_name = _('sun')
)
SETTINGS_TYPE = (
("BOOLEAN", "BOOLEAN"),
("INTEGER", "INTEGER"),
("LIST", "LIST"),
("STRING", "STRING"),
)
class Settings (DateModel, UserModel):
name = models.CharField(
verbose_name = "Name",
max_length = 100,
)
value = models.CharField(
verbose_name = "Value",
blank = True, null = True,
max_length = 500,
)
description = models.TextField(
verbose_name = "Description",
blank = True, null = True,
)
type = models.CharField(
max_length = 20,
choices = SETTINGS_TYPE,
verbose_name = _("Type"),
)
class Meta:
abstract = True
verbose_name = _("Settings")
verbose_name_plural = _("Settings")
def __unicode__(self):
return u"%s --> %s" % (self.name, self.value)
class CategoryModelManager(models.Manager):
def default(self):
return self.get_query_set().get(default=True)
class CategoryModel(DateModel, UserModel, StatusModel, OrderedModel):
objects = CategoryModelManager()
## campi modello
name = models.CharField(
unique=True,
max_length=25,
verbose_name=_('name'),
)
default = models.BooleanField(
default=False,
verbose_name=_('Default category'),
help_text=_('Is the default one?'),
)
def __unicode__(self):
return self.name
class Meta:
abstract = True
def save(self, *args, **kwargs):
super(CategoryModel, self).save(*args, **kwargs)
if self.default:
for c in CategoryModel.objects.exclude(pk=self.id):
c.default = False
c.save(*args, **kwargs)
try:
c = CategoryModel.objects.get(default=True)
except models.ObjectDoesNotExist:
self.default = True
super(CategoryModel, self).save(*args, **kwargs)