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]
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)
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)
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):
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):
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):