You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
2.1 KiB
63 lines
2.1 KiB
# -*- coding: utf-8 -*-
|
|
from operator import itemgetter
|
|
from django.utils.translation import ugettext as _
|
|
|
|
|
|
def base_concrete_model(abstract, instance):
|
|
"""
|
|
Used in methods of abstract models to find the super-most concrete
|
|
(non abstract) model in the inheritance chain that inherits from the
|
|
given abstract model. This is so the methods in the abstract model can
|
|
query data consistently across the correct concrete model.
|
|
|
|
Consider the following::
|
|
|
|
class Abstract(models.Model)
|
|
|
|
class Meta:
|
|
abstract = True
|
|
|
|
def concrete(self):
|
|
return base_concrete_model(Abstract, self)
|
|
|
|
class Super(Abstract):
|
|
pass
|
|
|
|
class Sub(Super):
|
|
pass
|
|
|
|
sub = Sub.objects.create()
|
|
sub.concrete() # returns Super
|
|
|
|
In actual Mezzanine usage, this allows methods in the ``Displayable`` and
|
|
``Orderable`` abstract models to access the ``Page`` instance when
|
|
instances of custom content types, (eg: models that inherit from ``Page``)
|
|
need to query the ``Page`` model to determine correct values for ``slug``
|
|
and ``_order`` which are only relevant in the context of the ``Page``
|
|
model and not the model of the custom content type.
|
|
"""
|
|
for cls in reversed(instance.__class__.__mro__):
|
|
if issubclass(cls, abstract) and not cls._meta.abstract:
|
|
return cls
|
|
return instance.__class__
|
|
|
|
|
|
class EnumChoices(list):
|
|
"""
|
|
A helper to create constants from choices tuples.
|
|
|
|
Usage:
|
|
CONNECTION_CHOICES = EnumChoices(
|
|
WIRED = (1, 'Wired connection'),
|
|
WIRELESS = (2, 'Wi-fi or other generic wireless type'),
|
|
MOBILE = (3, 'Mobile broadband'),
|
|
)
|
|
|
|
It will then return a list with the passed tuples so you can use in the
|
|
Django's fields choices option and, additionally, the returned object will
|
|
have the constant names as attributes (eg. CONNECTION_CHOICES.MOBILE == 3).
|
|
"""
|
|
def __init__(self, **data):
|
|
for item in sorted(data.items(), key=itemgetter(1)):
|
|
self.append((item[1][0], item[1][1]))
|
|
setattr(self, item[0], item[1][0])
|
|
|