Commits

Luke Plant committed 3cf4afa

Fixed issue #45 - incorrect serialisation of CssClass.templates to JSON

Fixed by using django-multiselectfield

Comments (0)

Files changed (4)

+Version 0.3.1
+-------------
+* Fixed issue with CssClass.templates field which could become corrupt via a
+  roundtrip through JSON. (It ended up with things like "u['']" etc.)  If this
+  affects you, you will need to manual check this field and correct it.
+
 Version 0.3
 -----------
 * Compatibility with django-cms 2.3 and 2.4

semanticeditor/admin.py

+from django import forms
 from django.contrib import admin
 from semanticeditor.models import CssClass, CssClassCategory
 
         }),
     )
 
+class CssClassForm(forms.ModelForm):
+    class Meta:
+        model = CssClass
+        widgets = {
+            'templates': forms.SelectMultiple,
+        }
+
+
 class CssClassAdmin(admin.ModelAdmin):
     list_display = ('verbose_name', 'name', 'category', 'allowed_elements')
     list_editable = ('name', 'category', 'allowed_elements')
+    form = CssClassForm
+
 
 class CssClassCategoryAdmin(admin.ModelAdmin):
     inlines = [CssClassAdminInline,]
-    
+
+
 admin.site.register(CssClass, CssClassAdmin)
-admin.site.register(CssClassCategory, CssClassCategoryAdmin)
+admin.site.register(CssClassCategory, CssClassCategoryAdmin)

semanticeditor/fields.py

-from django import forms
-from django.core import exceptions
-from django.db import models
-from django.utils.text import capfirst
+import multiselectfield
 
-# Thanks to danielroseman from djangosnippets.org for this code!
-
-class MultiSelectFormField(forms.MultipleChoiceField):
-    widget = forms.SelectMultiple
-
-    def __init__(self, *args, **kwargs):
-        self.max_choices = kwargs.pop('max_choices', 0)
-        super(MultiSelectFormField, self).__init__(*args, **kwargs)
-
-    def clean(self, value):
-        if not value and self.required:
-            raise forms.ValidationError(self.error_messages['required'])
-        if value and self.max_choices and len(value) > self.max_choices:
-            raise forms.ValidationError('You must select a maximum of %s choice%s.'
-                    % (apnumber(self.max_choices), pluralize(self.max_choices)))
-        return value
-
-    def widget_attrs(self, widget):
-        return {'class':'checkboxlist'}
-
-class MultiSelectField(models.Field):
-    __metaclass__ = models.SubfieldBase
+class MultiSelectField(multiselectfield.MultiSelectField):
 
     def get_internal_type(self):
         return "TextField"
 
-    def get_choices_default(self):
-        return self.get_choices(include_blank=False)
-
-    def _get_FIELD_display(self, field):
-        value = getattr(self, field.attname)
-        choicedict = dict(field.choices)
-
-    def formfield(self, **kwargs):
-        # don't call super, as that overrides default widget if it has choices
-        defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 
-                    'help_text': self.help_text, 'choices':self.choices}
-        if self.has_default():
-            defaults['initial'] = self.get_default()
-        defaults.update(kwargs)
-        return MultiSelectFormField(**defaults)
-
-    def get_db_prep_value(self, value, connection, prepared=False):
-        if isinstance(value, basestring):
-            return value
-        elif isinstance(value, list):
-            return ",".join(value)
-
-    def to_python(self, value):
-        if isinstance(value, list):
-            return value
-        elif value == None or value == u"":
-            return []
-        return value.split(",")
-
-    def contribute_to_class(self, cls, name):
-        super(MultiSelectField, self).contribute_to_class(cls, name)
-        if self.choices:
-            func = lambda self, fieldname = name, choicedict = dict(self.choices):",".join([choicedict.get(value,value) for value in getattr(self,fieldname)])
-            setattr(cls, 'get_%s_display' % self.name, func)
-
-    def validate(self, value, model_instance):
-        choice_keys = set(k for k, v in self._choices)
-        # value is a list of values
-        for v in value:
-            if v not in choice_keys:
-                raise exceptions.ValidationError(self.error_messages['invalid_choice'] % value)
-
 
 from south.modelsinspector import add_introspection_rules
 add_introspection_rules([], ["^semanticeditor\.fields\.MultiSelectField"])
         'Topic :: Internet :: WWW/HTTP',
         'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
     ],
-    install_requires = ['lxml >= 2.2.4', 'pyquery >= 0.6.1', 'django-cms >= 2.0'],
+    install_requires = ['lxml >= 2.2.4',
+                        'pyquery >= 0.6.1',
+                        'django-cms >= 2.0',
+                        'django-multiselectfield >= 0.0.2',
+                        ],
 )