+ def formfield(self, **kwargs):
+ defaults = {'required': False, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
+ if self.has_default():
+ defaults['initial'] = self.default
+ defaults.update(kwargs)
+ return self.field_template.formfield(**defaults)
+
+ def value_from_object(self, obj):
+ 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):
+ descriptor_class = ForeignKeyAttributeDescriptor
+
+ def __init__(self, model, limit_choices_to=None, key=None, **kwargs):
+ super(ForeignKeyAttribute, self).__init__(**kwargs)
+ self.key = key
+ self.model = model
+ if limit_choices_to is None:
+ limit_choices_to = {}
+ self.limit_choices_to = limit_choices_to
+
+ def formfield(self, form_class=forms.ModelChoiceField, **kwargs):
+ defaults = {'required': False, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
+ if self.has_default():
+ defaults['initial'] = self.default
+ defaults.update(kwargs)
+ return form_class(self.model._default_manager.complex_filter(self.limit_choices_to), **defaults)
+
+ def value_from_object(self, obj):
+ 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(ForeignKeyAttribute):
+ descriptor_class = ManyToManyAttributeDescriptor
+
+ 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)