mirror of
https://github.com/jazzband/django-eav2.git
synced 2026-04-28 02:44:44 +00:00
Fixed but of conflicting related names in generic relation
This commit is contained in:
parent
c4e0cd715f
commit
cd641d2714
4 changed files with 41 additions and 21 deletions
14
models.py
14
models.py
|
|
@ -180,9 +180,10 @@ class EavValue(models.Model):
|
|||
value_int = models.IntegerField(blank=True, null=True)
|
||||
value_date = models.DateTimeField(blank=True, null=True)
|
||||
value_bool = models.BooleanField(default=False)
|
||||
|
||||
generic_value_id = models.IntegerField(blank=True, null=True)
|
||||
generic_value_ct = models.ForeignKey(ContentType, blank=True, null=True,
|
||||
related_name='value_values')
|
||||
generic_value_id = models.IntegerField(blank=True, null=True)
|
||||
value_object = generic.GenericForeignKey(ct_field='generic_value_ct',
|
||||
fk_field='generic_value_id')
|
||||
|
||||
|
|
@ -202,10 +203,10 @@ class EavValue(models.Model):
|
|||
"""
|
||||
Set all the field to none
|
||||
"""
|
||||
self.value_bool = False
|
||||
for field in self._meta.fields:
|
||||
if field.name.startswith('value_') and field.null == True:
|
||||
setattr(self, field.name, None)
|
||||
self.value_bool = False
|
||||
|
||||
|
||||
def _get_value(self):
|
||||
|
|
@ -392,13 +393,4 @@ class EavEntity(object):
|
|||
def save_handler(sender, *args, **kwargs):
|
||||
kwargs['instance'].eav.save()
|
||||
|
||||
# TODO: remove that, it's just for testing with nose
|
||||
|
||||
class Patient(models.Model):
|
||||
class Meta:
|
||||
app_label = 'eav_ng'
|
||||
|
||||
name = models.CharField(max_length=20)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
|
|
|||
|
|
@ -32,14 +32,15 @@ class EavBasicTests(TestCase):
|
|||
EavRegistry.unregister(Patient)
|
||||
|
||||
|
||||
def test_attribute_unicode(self):
|
||||
self.assertEqual(unicode(self.attribute), "City (Text)")
|
||||
|
||||
|
||||
def test_can_create_attribute(self):
|
||||
EavAttribute.objects.create(datatype=EavAttribute.TYPE_TEXT,
|
||||
name='My text test', slug='test',
|
||||
help_text='My help text')
|
||||
|
||||
def test_attribute_unicode(self):
|
||||
self.assertEqual(unicode(self.attribute), "City (Text)")
|
||||
|
||||
|
||||
def test_can_eaventity_children_give_you_all_attributes_by_default(self):
|
||||
qs = Patient.eav.get_eav_attributes()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
from django.db import models
|
||||
|
||||
from ..utils import EavRegistry
|
||||
|
||||
class Patient(models.Model):
|
||||
class Meta:
|
||||
|
|
@ -10,3 +9,4 @@ class Patient(models.Model):
|
|||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
|
|
|||
39
utils.py
39
utils.py
|
|
@ -1,15 +1,18 @@
|
|||
from django.contrib.contenttypes import generic
|
||||
from django.db.utils import DatabaseError
|
||||
from django.db.models.signals import post_init, post_save, post_delete
|
||||
from django.db.models.signals import post_init, post_save, post_delete, pre_init
|
||||
from .managers import EntityManager
|
||||
from .models import (EavEntity, EavAttribute, EavValue,
|
||||
get_unique_class_identifier)
|
||||
|
||||
|
||||
#todo : rename this file in registry
|
||||
class EavConfig(EavEntity):
|
||||
|
||||
proxy_field_name = 'eav'
|
||||
manager_field_name ='objects'
|
||||
generic_relation_field_name = 'eav_values'
|
||||
generic_relation_field_related_name = None
|
||||
|
||||
@classmethod
|
||||
def get_eav_attributes(cls):
|
||||
|
|
@ -64,7 +67,8 @@ class EavRegistry(object):
|
|||
def wrap_config_class(model_cls, config_cls):
|
||||
"""
|
||||
Check if the config class is EavConfig, and create a subclass if
|
||||
it is
|
||||
it is. We don't want to use eav_config directly since we use the
|
||||
class as a name space
|
||||
"""
|
||||
if config_cls is EavConfig:
|
||||
return type("%sConfig" % model_cls.__name__, (EavConfig,), {})
|
||||
|
|
@ -84,34 +88,51 @@ class EavRegistry(object):
|
|||
return
|
||||
|
||||
config_cls = EavRegistry.wrap_config_class(model_cls, config_cls)
|
||||
|
||||
# we want to call attach and save handler on instance creation and
|
||||
# saving
|
||||
post_init.connect(EavRegistry.attach, sender=model_cls)
|
||||
post_save.connect(EavEntity.save_handler, sender=model_cls)
|
||||
|
||||
# todo: rename cache in data
|
||||
EavRegistry.cache[cls_id] = { 'config_cls': config_cls,
|
||||
'model_cls': model_cls }
|
||||
|
||||
# save the old manager if the attribute name conflict with the new
|
||||
# one
|
||||
if hasattr(model_cls, config_cls.manager_field_name):
|
||||
mgr = getattr(model_cls, config_cls.manager_field_name)
|
||||
EavRegistry.cache[cls_id]['old_mgr'] = mgr
|
||||
|
||||
# set add the config_cls as an attribute of the model
|
||||
# it will allow to perform some operation directly from this model
|
||||
setattr(model_cls, config_cls.proxy_field_name, config_cls)
|
||||
|
||||
# todo : not useful anymore ?
|
||||
setattr(getattr(model_cls, config_cls.proxy_field_name),
|
||||
'get_eav_attributes', config_cls.get_eav_attributes)
|
||||
|
||||
# attache the new manager to the model
|
||||
mgr = EntityManager()
|
||||
mgr.contribute_to_class(model_cls, config_cls.manager_field_name)
|
||||
|
||||
|
||||
# todo: see with david how to change that
|
||||
try:
|
||||
EavEntity.update_attr_cache_for_model(model_cls)
|
||||
except DatabaseError:
|
||||
pass
|
||||
|
||||
# todo: make that overridable
|
||||
# attache the generic relation to the model
|
||||
if config_cls.generic_relation_field_related_name:
|
||||
rel_name = config_cls.generic_relation_field_related_name
|
||||
else:
|
||||
rel_name = model_cls.__name__
|
||||
gr_name = config_cls.generic_relation_field_name
|
||||
generic_relation = generic.GenericRelation(EavValue,
|
||||
object_id_field='entity_id',
|
||||
content_type_field='entity_ct',
|
||||
related_name=model_cls.__name__)
|
||||
related_name=rel_name)
|
||||
generic_relation.contribute_to_class(model_cls, gr_name)
|
||||
|
||||
|
||||
|
|
@ -136,11 +157,17 @@ class EavRegistry(object):
|
|||
except AttributeError:
|
||||
pass
|
||||
|
||||
# remove remaining reference to the generic relation
|
||||
gen_rel_field = config_cls.generic_relation_field_name
|
||||
for field in model_cls._meta.local_many_to_many:
|
||||
if field.name == gen_rel_field:
|
||||
model_cls._meta.local_many_to_many.remove(field)
|
||||
break
|
||||
try:
|
||||
delattr(model_cls, config_cls.generic_relation_field_name)
|
||||
#delattr(EavValue, config_cls.generic_relation_field_name)
|
||||
delattr(model_cls, gen_rel_field)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
if 'old_mgr' in cache:
|
||||
cache['old_mgr'].contribute_to_class(model_cls,
|
||||
|
|
|
|||
Loading…
Reference in a new issue