X-Git-Url: http://git.ithinksw.org/philo.git/blobdiff_plain/98bd3a178f3e62e5591e809ac61e07a5bf37c292..19e0d1e6a2bb46d46b988fbad188d8dd4288bf5e:/models/fields.py diff --git a/models/fields.py b/models/fields.py index 0c68858..74a0525 100644 --- a/models/fields.py +++ b/models/fields.py @@ -47,9 +47,9 @@ class AttributeFieldDescriptor(object): def __get__(self, instance, owner): if instance: - if self.field.key in instance._added_attribute_registry: - return instance._added_attribute_registry[self.field.key] - if self.field.key in instance._removed_attribute_registry: + if self.field in instance._added_attribute_registry: + return instance._added_attribute_registry[self.field] + if self.field in instance._removed_attribute_registry: return None try: return instance.attributes[self.field.key] @@ -62,24 +62,24 @@ class AttributeFieldDescriptor(object): raise NotImplementedError('AttributeFieldDescriptor subclasses must implement a __set__ method.') def __delete__(self, instance): - if self.field.key in instance._added_attribute_registry: - del instance._added_attribute_registry[self.field.key] - instance._removed_attribute_registry.append(self.field.key) + if self.field in instance._added_attribute_registry: + del instance._added_attribute_registry[self.field] + instance._removed_attribute_registry.append(self.field) class JSONAttributeDescriptor(AttributeFieldDescriptor): def __set__(self, instance, value): - if self.field.key in instance._removed_attribute_registry: - instance._removed_attribute_registry.remove(self.field.key) - instance._added_attribute_registry[self.field.key] = value + if self.field in instance._removed_attribute_registry: + instance._removed_attribute_registry.remove(self.field) + instance._added_attribute_registry[self.field] = value class ForeignKeyAttributeDescriptor(AttributeFieldDescriptor): def __set__(self, instance, value): if isinstance(value, (models.Model, type(None))): - if self.field.key in instance._removed_attribute_registry: - instance._removed_attribute_registry.remove(self.field.key) - instance._added_attribute_registry[self.field.key] = value + if self.field in instance._removed_attribute_registry: + instance._removed_attribute_registry.remove(self.field) + instance._added_attribute_registry[self.field] = value else: raise AttributeError('The \'%s\' attribute can only be set using existing Model objects.' % self.field.name) @@ -87,9 +87,9 @@ class ForeignKeyAttributeDescriptor(AttributeFieldDescriptor): class ManyToManyAttributeDescriptor(AttributeFieldDescriptor): def __set__(self, instance, value): if isinstance(value, models.QuerySet): - if self.field.key in instance._removed_attribute_registry: - instance._removed_attribute_registry.remove(self.field.key) - instance._added_attribute_registry[self.field.key] = value + if self.field in instance._removed_attribute_registry: + instance._removed_attribute_registry.remove(self.field) + instance._added_attribute_registry[self.field] = value else: raise AttributeError('The \'%s\' attribute can only be set to a QuerySet.' % self.field.name) @@ -99,6 +99,17 @@ class AttributeField(EntityProxyField): super(AttributeField, self).contribute_to_class(cls, name) if self.key is None: self.key = name + + def set_attribute_value(self, attribute, value, value_class): + if not isinstance(attribute.value, value_class): + if isinstance(attribute.value, models.Model): + attribute.value.delete() + new_value = value_class() + else: + new_value = attribute.value + new_value.value = value + new_value.save() + attribute.value = new_value class JSONAttribute(AttributeField): @@ -117,7 +128,16 @@ class JSONAttribute(AttributeField): return self.field_template.formfield(**defaults) def value_from_object(self, obj): - return getattr(obj, self.attname).value + try: + return getattr(obj, self.attname) + except AttributeError: + return None + + def set_attribute_value(self, attribute, value, value_class=None): + if value_class is None: + from philo.models.base import JSONValue + value_class = JSONValue + super(JSONAttribute, self).set_attribute_value(attribute, value, value_class) class ForeignKeyAttribute(AttributeField): @@ -137,13 +157,30 @@ class ForeignKeyAttribute(AttributeField): return form_class(self.model._default_manager.complex_filter(self.limit_choices_to), **defaults) def value_from_object(self, obj): - relobj = super(ForeignKeyAttribute, self).value_from_object(obj).value + try: + relobj = super(ForeignKeyAttribute, self).value_from_object(obj) + except AttributeError: + return None return getattr(relobj, 'pk', None) + + def set_attribute_value(self, attribute, value, value_class=None): + if value_class is None: + from philo.models.base import ForeignKeyValue + value_class = ForeignKeyValue + super(ForeignKeyAttribute, self).set_attribute_value(attribute, value, value_class) -class ManyToManyAttribute(AttributeField): +class ManyToManyAttribute(ForeignKeyAttribute): descriptor_class = ManyToManyAttributeDescriptor - #FIXME: Add __init__ and formfield methods + + def formfield(self, form_class=forms.ModelMultipleChoiceField, **kwargs): + return super(ManyToManyAttribute, self).formfield(form_class, **kwargs) + + def set_attribute_value(self, attribute, value, value_class=None): + if value_class is None: + from philo.models.base import ManyToManyValue + value_class = ManyToManyValue + super(ManyToManyAttribute, self).set_attribute_value(attribute, value, value_class) class TemplateField(models.TextField):