From: Stephen Burrows Date: Tue, 25 Jan 2011 16:15:06 +0000 (-0500) Subject: Added support for DateTime information being stored in a JSONAttribute. Switched... X-Git-Tag: philo-0.9~22^2^2~1 X-Git-Url: http://git.ithinksw.org/philo.git/commitdiff_plain/fbe780ee3c39c4feea456aa9d36c89467900191c Added support for DateTime information being stored in a JSONAttribute. Switched ForeignKeyAttribute and M2MAttribute to store the related model in self.to instead of overwriting self.model. --- diff --git a/contrib/cowell/fields.py b/contrib/cowell/fields.py index c5db56d..176554e 100644 --- a/contrib/cowell/fields.py +++ b/contrib/cowell/fields.py @@ -23,6 +23,7 @@ from django.db.models.fields import NOT_PROVIDED from django.utils.text import capfirst from philo.signals import entity_class_prepared from philo.models import ManyToManyValue, JSONValue, ForeignKeyValue, Attribute, Entity +import datetime __all__ = ('JSONAttribute', 'ForeignKeyAttribute', 'ManyToManyAttribute') @@ -68,6 +69,11 @@ class EntityProxyField(object): this field's initial value.""" return getattr(obj, self.name) + def get_storage_value(self, value): + """Final conversion of `value` before it gets stored on an Entity instance. + This step is performed by the ProxyFieldForm.""" + return value + def has_default(self): return self.default is not NOT_PROVIDED @@ -158,7 +164,6 @@ class AttributeField(EntityProxyField): if not hasattr(opts, '_has_attribute_fields'): opts._has_attribute_fields = True models.signals.post_save.connect(process_attribute_fields, sender=sender) - def contribute_to_class(self, cls, name): if self.attribute_key is None: @@ -167,7 +172,7 @@ class AttributeField(EntityProxyField): def validate_value(self, value): "Confirm that the value is valid or raise an appropriate error." - raise NotImplementedError("validate_value must be implemented by AttributeField subclasses.") + pass @property def value_class(self): @@ -183,9 +188,6 @@ class JSONAttribute(AttributeField): field_template = models.CharField(max_length=255) self.field_template = field_template - def validate_value(self, value): - pass - def formfield(self, **kwargs): defaults = { 'required': False, @@ -196,6 +198,19 @@ class JSONAttribute(AttributeField): defaults['initial'] = self.default defaults.update(kwargs) return self.field_template.formfield(**defaults) + + def value_from_object(self, obj): + value = super(JSONAttribute, self).value_from_object(obj) + if isinstance(self.field_template, (models.DateField, models.DateTimeField)): + value = self.field_template.to_python(value) + return value + + def get_storage_value(self, value): + if isinstance(value, datetime.datetime): + return value.strftime("%Y-%m-%d %H:%M:%S") + if isinstance(value, datetime.date): + return value.strftime("%Y-%m-%d") + return value class ForeignKeyAttribute(AttributeField): @@ -203,18 +218,18 @@ class ForeignKeyAttribute(AttributeField): def __init__(self, model, limit_choices_to=None, **kwargs): super(ForeignKeyAttribute, self).__init__(**kwargs) - self.model = model + self.to = model if limit_choices_to is None: limit_choices_to = {} self.limit_choices_to = limit_choices_to def validate_value(self, value): - if value is not None and not isinstance(value, self.model) : - raise TypeError("The '%s' attribute can only be set to an instance of %s or None." % (self.name, self.model.__name__)) + if value is not None and not isinstance(value, self.to) : + raise TypeError("The '%s' attribute can only be set to an instance of %s or None." % (self.name, self.to.__name__)) def formfield(self, form_class=forms.ModelChoiceField, **kwargs): defaults = { - 'queryset': self.model._default_manager.complex_filter(self.limit_choices_to) + 'queryset': self.to._default_manager.complex_filter(self.limit_choices_to) } defaults.update(kwargs) return super(ForeignKeyAttribute, self).formfield(form_class=form_class, **defaults) @@ -223,22 +238,17 @@ class ForeignKeyAttribute(AttributeField): relobj = super(ForeignKeyAttribute, self).value_from_object(obj) return getattr(relobj, 'pk', None) - @property - def to(self): - """Spoof being a rel from a ForeignKey.""" - return self.model - def get_related_field(self): - """Again, spoof being a rel from a ForeignKey.""" - return self.model._meta.pk + """Spoof being a rel from a ForeignKey.""" + return self.to._meta.pk class ManyToManyAttribute(ForeignKeyAttribute): value_class = ManyToManyValue def validate_value(self, value): - if not isinstance(value, models.query.QuerySet) or value.model != self.model: - raise TypeError("The '%s' attribute can only be set to a %s QuerySet." % (self.name, self.model.__name__)) + if not isinstance(value, models.query.QuerySet) or value.model != self.to: + raise TypeError("The '%s' attribute can only be set to a %s QuerySet." % (self.name, self.to.__name__)) def formfield(self, form_class=forms.ModelMultipleChoiceField, **kwargs): return super(ManyToManyAttribute, self).formfield(form_class=form_class, **kwargs) diff --git a/contrib/cowell/forms.py b/contrib/cowell/forms.py index 0b5a0c6..aa8b6ca 100644 --- a/contrib/cowell/forms.py +++ b/contrib/cowell/forms.py @@ -90,7 +90,7 @@ class ProxyFieldForm(ProxyFieldFormBase): # Would inherit from ModelForm directl continue if self._meta.exclude and f.name in self._meta.exclude: continue - setattr(instance, f.attname, cleaned_data[f.name]) + setattr(instance, f.attname, f.get_storage_value(cleaned_data[f.name])) if commit: instance.save()