X-Git-Url: http://git.ithinksw.org/philo.git/blobdiff_plain/74ceac458ad030558f2e564ba34191115d0aadc5..9bbc541d5a4a8720fbfa24c081da574cb1822df7:/forms.py?ds=sidebyside diff --git a/forms.py b/forms.py index 0e034df..69273f0 100644 --- a/forms.py +++ b/forms.py @@ -7,7 +7,7 @@ from django.forms.formsets import TOTAL_FORM_COUNT from django.template import loader, loader_tags, TemplateDoesNotExist, Context, Template as DjangoTemplate from django.utils.datastructures import SortedDict from philo.admin.widgets import ModelLookupWidget -from philo.models import Entity, Template, Contentlet, ContentReference +from philo.models import Entity, Template, Contentlet, ContentReference, Attribute from philo.utils import fattr @@ -95,6 +95,61 @@ class EntityForm(EntityFormBase): # Would inherit from ModelForm directly if it return instance +class AttributeForm(ModelForm): + def __init__(self, *args, **kwargs): + super(AttributeForm, self).__init__(*args, **kwargs) + + # This is necessary because model forms store changes to self.instance in their clean method. + # Mutter mutter. + self._cached_value_ct = self.instance.value_content_type + self._cached_value = self.instance.value + + if self.instance.value is not None: + value_field = self.instance.value.value_formfield() + if value_field: + self.fields['value'] = value_field + if hasattr(self.instance.value, 'content_type'): + self.fields['content_type'] = self.instance.value._meta.get_field('content_type').formfield(initial=getattr(self.instance.value.content_type, 'pk', None)) + + def save(self, *args, **kwargs): + # At this point, the cleaned_data has already been stored on self.instance. + if self.instance.value_content_type != self._cached_value_ct: + if self.instance.value is not None: + self._cached_value.delete() + if 'value' in self.cleaned_data: + del(self.cleaned_data['value']) + + if self.instance.value_content_type is not None: + # Make a blank value of the new type! Run special code for content_type attributes. + if hasattr(self.instance.value_content_type.model_class(), 'content_type'): + if self._cached_value and hasattr(self._cached_value, 'content_type'): + new_ct = self._cached_value.content_type + else: + new_ct = None + new_value = self.instance.value_content_type.model_class().objects.create(content_type=new_ct) + else: + new_value = self.instance.value_content_type.model_class().objects.create() + + new_value.apply_data(self.cleaned_data) + new_value.save() + self.instance.value = new_value + else: + # The value type is the same, but one of the fields has changed. + # Check to see if the changed value was the content type. We have to check the + # cleaned_data because self.instance.value.content_type was overridden. + if hasattr(self.instance.value, 'content_type') and 'content_type' in self.cleaned_data and 'value' in self.cleaned_data and (not hasattr(self._cached_value, 'content_type') or self._cached_value.content_type != self.cleaned_data['content_type']): + self.cleaned_data['value'] = None + + self.instance.value.apply_data(self.cleaned_data) + self.instance.value.save() + + super(AttributeForm, self).save(*args, **kwargs) + return self.instance + + class Meta: + model = Attribute + + class ContainerForm(ModelForm): def __init__(self, *args, **kwargs): super(ContainerForm, self).__init__(*args, **kwargs)