mirror of
https://github.com/jazzband/django-eav2.git
synced 2026-03-16 22:40:26 +00:00
92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
from django.db.models.signals import post_init, pre_save
|
|
from .managers import EntityManager
|
|
from .models import EavEntity, EavAttribute
|
|
|
|
class EavConfig(object):
|
|
@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
|
|
"""
|
|
field_cache = {}
|
|
|
|
@staticmethod
|
|
def attach(sender, *args, **kwargs):
|
|
"""
|
|
Attache EAV toolkit to an instance after init.
|
|
"""
|
|
instance = kwargs['instance']
|
|
cls = instance.__class__
|
|
|
|
proxy_name = EavRegistry.field_cache[cls.__name__]['proxy']
|
|
|
|
setattr(instance, proxy_name, EavEntity(instance))
|
|
|
|
|
|
@staticmethod
|
|
def register(model_cls, admin_cls=EavConfig, eav_proxy_field='eav',
|
|
eav_manager_field='objects'):
|
|
"""
|
|
Inject eav features into the given model and attach a signal
|
|
listener to it for setup.
|
|
"""
|
|
if model_cls.__name__ in EavRegistry.field_cache:
|
|
return
|
|
|
|
post_init.connect(EavRegistry.attach, sender=model_cls)
|
|
pre_save.connect(EavEntity.pre_save_handler, sender=model_cls)
|
|
EavRegistry.field_cache[model_cls.__name__] = {
|
|
'proxy': eav_proxy_field,
|
|
'mgr': eav_manager_field}
|
|
|
|
if hasattr(model_cls, eav_manager_field):
|
|
mgr = getattr(model_cls, eav_manager_field)
|
|
EavRegistry.field_cache[model_cls.__name__]['old_mgr'] = mgr
|
|
|
|
setattr(model_cls, eav_proxy_field, EavEntity)
|
|
|
|
setattr(getattr(model_cls, eav_proxy_field),
|
|
'get_eav_attributes', admin_cls.get_eav_attributes)
|
|
|
|
mgr = EntityManager()
|
|
mgr.contribute_to_class(model_cls, eav_manager_field)
|
|
|
|
|
|
@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.field_cache:
|
|
return
|
|
|
|
cache = EavRegistry.field_cache[model_cls.__name__]
|
|
post_init.disconnect(EavRegistry.attach, sender=model_cls)
|
|
pre_save.disconnect(EavEntity.pre_save_handler, sender=model_cls)
|
|
proxy_name = cache['proxy']
|
|
mgr_name = cache['mgr']
|
|
|
|
try:
|
|
delattr(model_cls, mgr_name)
|
|
except AttributeError:
|
|
pass
|
|
|
|
if 'old_mgr' in cache:
|
|
cache['old_mgr'].contribute_to_class(model_cls, mgr_name)
|
|
|
|
try:
|
|
delattr(model_cls, proxy_name)
|
|
except AttributeError:
|
|
pass
|
|
|
|
EavRegistry.field_cache.pop(model_cls.__name__)
|
|
|