Added AttributeForm to elegantly handle all the fields that should be displayed in...
authorStephen Burrows <stephen.r.burrows@gmail.com>
Tue, 12 Oct 2010 16:30:34 +0000 (12:30 -0400)
committerStephen Burrows <stephen.r.burrows@gmail.com>
Tue, 12 Oct 2010 16:34:31 +0000 (12:34 -0400)
admin/base.py
forms.py
models/base.py
templates/admin/philo/edit_inline/tabular_attribute.html [moved from templates/admin/philo/edit_inline/tabular_collapse.html with 97% similarity]

index 3b2deba..d9249e5 100644 (file)
@@ -1,6 +1,7 @@
 from django.contrib import admin
 from django.contrib.contenttypes import generic
 from philo.models import Tag, Attribute
+from philo.forms import AttributeForm
 
 
 COLLAPSE_CLASSES = ('collapse', 'collapse-closed', 'closed',)
@@ -11,23 +12,15 @@ class AttributeInline(generic.GenericTabularInline):
        ct_fk_field = 'entity_object_id'
        model = Attribute
        extra = 1
-       template = 'admin/philo/edit_inline/tabular_collapse.html'
+       template = 'admin/philo/edit_inline/tabular_attribute.html'
        allow_add = True
        classes = COLLAPSE_CLASSES
-
-
-#class RelationshipInline(generic.GenericTabularInline):
-#      ct_field = 'entity_content_type'
-#      ct_fk_field = 'entity_object_id'
-#      model = Relationship
-#      extra = 1
-#      template = 'admin/philo/edit_inline/tabular_collapse.html'
-#      allow_add = True
-#      classes = COLLAPSE_CLASSES
+       form = AttributeForm
+       exclude = ['value_object_id']
 
 
 class EntityAdmin(admin.ModelAdmin):
-       inlines = [AttributeInline] #, RelationshipInline]
+       inlines = [AttributeInline]
        save_on_top = True
 
 
index 0e034df..c864f31 100644 (file)
--- 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,35 @@ 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)
+               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):
+               instance = super(AttributeForm, self).save(*args, **kwargs)
+               
+               if self.cleaned_data['value_content_type'] != self.instance.value_content_type:
+                       if self.instance.value is not None:
+                               self.instance.value.delete()
+                               del(self.cleaned_data['value'])
+               elif 'content_type' in self.cleaned_data and self.cleaned_data['content_type'] != self.instance.value.content_type:
+                       self.instance.value.content_type = self.cleaned_data['content_type']
+                       self.instance.value.save()
+               elif 'value' in self.cleaned_data:
+                       self.instance.set_value(self.cleaned_data['value'])
+               
+               return instance
+       
+       class Meta:
+               model = Attribute
+
+
 class ContainerForm(ModelForm):
        def __init__(self, *args, **kwargs):
                super(ContainerForm, self).__init__(*args, **kwargs)
index 145c1ee..cd25357 100644 (file)
@@ -1,3 +1,4 @@
+from django import forms
 from django.db import models
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes import generic
@@ -50,6 +51,10 @@ class JSONValue(models.Model):
        def __unicode__(self):
                return self.value_json
        
+       def value_formfield(self, *args, **kwargs):
+               kwargs['initial'] = self.value_json
+               return self._meta.get_field('value').formfield(*args, **kwargs)
+       
        class Meta:
                app_label = 'philo'
 
@@ -62,6 +67,12 @@ class ForeignKeyValue(models.Model):
        def __unicode__(self):
                return unicode(self.value)
        
+       def value_formfield(self, form_class=forms.ModelChoiceField, **kwargs):
+               if self.content_type is None:
+                       return None
+               kwargs.update({'initial': self.object_id, 'required': False})
+               return form_class(self.content_type.model_class()._default_manager.all(), **kwargs)
+       
        class Meta:
                app_label = 'philo'
 
@@ -108,7 +119,7 @@ class Attribute(models.Model):
        def get_value_class(self, value):
                if isinstance(value, models.query.QuerySet):
                        return ManyToManyValue
-               elif isinstance(value, models.Model):
+               elif isinstance(value, models.Model) or (value is None and self.value_content_type.model_class() is ForeignKeyValue):
                        return ForeignKeyValue
                else:
                        return JSONValue
@@ -12,6 +12,8 @@
          <th{% if forloop.first %} colspan="2"{% endif %}{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}</th>
        {% endif %}
      {% endfor %}
+         <th>Content Type</th>
+         <th>Value</th>
      {% if inline_admin_formset.formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %}
      </tr></thead>
 
@@ -53,6 +55,8 @@
             {% endfor %}
           {% endfor %}
         {% endfor %}
+        <td>{{ inline_admin_form.form.content_type }}</td>
+        <td>{{ inline_admin_form.form.value }}</td>
         {% if inline_admin_formset.formset.can_delete %}
           <td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td>
         {% endif %}