django-eav2/utils.py

95 lines
2.9 KiB
Python
Raw Normal View History

from django.db.models.signals import post_init, post_save
2010-09-06 21:22:41 +00:00
from .managers import EntityManager
from .models import EavEntity, EavAttribute
2010-09-06 20:46:11 +00:00
2010-09-06 21:22:41 +00:00
class EavConfig(object):
proxy_field_name = 'eav'
manager_field_name ='objects'
2010-09-06 20:46:11 +00:00
@classmethod
def get_eav_attributes(cls):
"""
By default, all attributes apply to an entity,
unless otherwise specified.
"""
return EavAttribute.objects.all()
class EavRegistry(object):
"""
Tools to add eav features to models
"""
cache = {}
2010-09-06 20:46:11 +00:00
@staticmethod
def attach(sender, *args, **kwargs):
"""
Attache EAV toolkit to an instance after init.
"""
instance = kwargs['instance']
cls = instance.__class__
admin_cls = EavRegistry.cache[cls.__name__]['admin_cls']
2010-09-06 20:46:11 +00:00
setattr(instance, admin_cls.proxy_field_name, EavEntity(instance))
2010-09-06 20:46:11 +00:00
@staticmethod
def register(model_cls, admin_cls=EavConfig):
2010-09-06 20:46:11 +00:00
"""
Inject eav features into the given model and attach a signal
listener to it for setup.
"""
if model_cls.__name__ in EavRegistry.cache:
2010-09-06 20:46:11 +00:00
return
post_init.connect(EavRegistry.attach, sender=model_cls)
post_save.connect(EavEntity.save_handler, sender=model_cls)
EavRegistry.cache[model_cls.__name__] = { 'admin_cls':
admin_cls }
2010-09-06 20:46:11 +00:00
if hasattr(model_cls, admin_cls.manager_field_name):
mgr = getattr(model_cls, admin_cls.manager_field_name)
EavRegistry.cache[model_cls.__name__]['old_mgr'] = mgr
2010-09-06 20:46:11 +00:00
setattr(model_cls, admin_cls.proxy_field_name, EavEntity)
2010-09-06 20:46:11 +00:00
setattr(getattr(model_cls, admin_cls.proxy_field_name),
2010-09-06 20:46:11 +00:00
'get_eav_attributes', admin_cls.get_eav_attributes)
mgr = EntityManager()
mgr.contribute_to_class(model_cls, admin_cls.manager_field_name)
2010-09-06 20:46:11 +00:00
@staticmethod
def unregister(model_cls):
"""
Inject eav features into the given model and attach a signal
listener to it for setup.
"""
if not model_cls.__name__ in EavRegistry.cache:
2010-09-06 20:46:11 +00:00
return
cache = EavRegistry.cache[model_cls.__name__]
admin_cls = cache['admin_cls']
2010-09-06 20:46:11 +00:00
post_init.disconnect(EavRegistry.attach, sender=model_cls)
post_save.disconnect(EavEntity.save_handler, sender=model_cls)
2010-09-06 20:46:11 +00:00
try:
delattr(model_cls, admin_cls.manager_field_name)
2010-09-06 20:46:11 +00:00
except AttributeError:
pass
if 'old_mgr' in cache:
cache['old_mgr'].contribute_to_class(model_cls,
admin_cls.manager_field_name)
2010-09-06 20:46:11 +00:00
try:
delattr(model_cls, admin_cls.proxy_field_name)
2010-09-06 20:46:11 +00:00
except AttributeError:
pass
EavRegistry.cache.pop(model_cls.__name__)
2010-09-06 20:46:11 +00:00