team-3/src/c3nav/mapdata/models/base.py

103 lines
3.3 KiB
Python
Raw Normal View History

from collections import OrderedDict
2017-05-07 12:06:13 +02:00
2017-10-19 13:55:35 +02:00
from django.core.cache import cache
2017-05-09 13:32:32 +02:00
from django.db import models
2017-05-26 21:25:54 +02:00
from django.utils.translation import ugettext_lazy as _
2017-07-10 13:01:35 +02:00
from django.utils.translation import get_language
from c3nav.mapdata.fields import JSONField
2017-10-19 13:55:35 +02:00
from c3nav.mapdata.models import MapUpdate
2016-11-27 23:51:44 +01:00
class SerializableMixin(models.Model):
class Meta:
abstract = True
2017-05-11 19:36:49 +02:00
def serialize(self, **kwargs):
return self._serialize(**kwargs)
2017-05-11 21:30:29 +02:00
@classmethod
def serialize_type(cls, **kwargs):
return OrderedDict((
('name', cls.__name__.lower()),
('name_plural', cls._meta.default_related_name),
('title', str(cls._meta.verbose_name)),
('title_plural', str(cls._meta.verbose_name_plural)),
))
2017-05-11 19:36:49 +02:00
def _serialize(self, include_type=False, **kwargs):
result = OrderedDict()
if include_type:
result['type'] = self.__class__.__name__.lower()
2017-06-16 18:19:52 +02:00
result['id'] = self.pk
2017-05-11 19:36:49 +02:00
return result
@property
def title(self):
return self._meta.verbose_name + ' ' + str(self.id)
2017-05-26 21:25:54 +02:00
2017-07-10 13:01:35 +02:00
class TitledMixin(SerializableMixin, models.Model):
titles = JSONField(default={})
class Meta:
abstract = True
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.titles = self.titles.copy()
def serialize(self, detailed=True, **kwargs):
result = super().serialize(detailed=detailed, **kwargs)
if not detailed:
result.pop('title', None)
return result
def _serialize(self, **kwargs):
result = super()._serialize(**kwargs)
result['titles'] = self.titles
result['title'] = self.title
return result
@property
def title(self):
lang = get_language()
if self.titles:
if lang in self.titles:
return self.titles[lang]
return next(iter(self.titles.values()))
return super().title
2017-05-26 21:25:54 +02:00
class BoundsMixin(SerializableMixin, models.Model):
bottom = models.DecimalField(_('bottom coordinate'), max_digits=6, decimal_places=2)
left = models.DecimalField(_('left coordinate'), max_digits=6, decimal_places=2)
top = models.DecimalField(_('top coordinate'), max_digits=6, decimal_places=2)
right = models.DecimalField(_('right coordinate'), max_digits=6, decimal_places=2)
class Meta:
abstract = True
@classmethod
def max_bounds(cls):
2017-10-23 22:49:45 +02:00
cache_key = 'mapdata:max_bounds:%s:%s' % (cls.__name__, MapUpdate.current_cache_key())
2017-10-19 13:55:35 +02:00
result = cache.get(cache_key, None)
if result is not None:
return result
2017-05-26 21:25:54 +02:00
result = cls.objects.all().aggregate(models.Min('bottom'), models.Min('left'),
models.Max('top'), models.Max('right'))
2017-10-19 13:55:35 +02:00
result = ((float(result['bottom__min']), float(result['left__min'])),
(float(result['top__max']), float(result['right__max'])))
cache.set(cache_key, result, 900)
return result
2017-05-26 21:25:54 +02:00
2017-06-11 14:43:14 +02:00
def _serialize(self, level=True, **kwargs):
2017-05-26 21:25:54 +02:00
result = super()._serialize(**kwargs)
result['bounds'] = self.bounds
return result
@property
def bounds(self):
# noinspection PyTypeChecker
return (float(self.bottom), float(self.left)), (float(self.top), float(self.right))