Changed JSONField implementation. Now to get and set decoded value you must use get_...
authorMarek Stępniowski <marek@stepniowski.com>
Sat, 29 Nov 2008 22:40:20 +0000 (23:40 +0100)
committerMarek Stępniowski <marek@stepniowski.com>
Mon, 1 Dec 2008 19:04:48 +0000 (20:04 +0100)
This fixes a bug during saving book info in admin.

apps/catalogue/fields.py
apps/catalogue/models.py
apps/catalogue/views.py
wolnelektury/templates/catalogue/book_detail.html

index d091b77..eedff67 100644 (file)
@@ -31,36 +31,39 @@ def loads(str):
     return json.loads(str, encoding=settings.DEFAULT_CHARSET)
 
 
+class JSONFormField(forms.CharField):
+    widget = forms.Textarea
+    
+    def clean(self, value):
+        try:
+            loads(value)
+            return value
+        except ValueError, e:
+            raise forms.ValidationError('Enter a valid JSON value. Error: %s' % e)
+
+
 class JSONField(models.TextField):
+    def formfield(self, **kwargs):
+        defaults = {'form_class': JSONFormField}
+        defaults.update(kwargs)
+        return super(JSONField, self).formfield(**defaults)
+
     def db_type(self):
         return 'text'
-    
+
     def get_internal_type(self):
         return 'TextField'
 
-    def pre_save(self, model_instance, add):
-        value = getattr(model_instance, self.attname, None)
-        return dumps(value)
-
     def contribute_to_class(self, cls, name):
         super(JSONField, self).contribute_to_class(cls, name)
-        signals.post_init.connect(self.post_init, sender=cls)
-
-        def get_json(model_instance):
-            return dumps(getattr(model_instance, self.attname, None))
-        setattr(cls, 'get_%s_json' % self.name, get_json)
-
-        def set_json(model_instance, json):
-            return setattr(model_instance, self.attname, loads(json))
-        setattr(cls, 'set_%s_json' % self.name, set_json)
-
-    def post_init(self, **kwargs):
-        instance = kwargs.get('instance', None)
-        value = self.value_from_object(instance)
-        if (value):
-            setattr(instance, self.attname, loads(value))
-        else:
-            setattr(instance, self.attname, None)
+        
+        def get_value(model_instance):
+            return loads(getattr(model_instance, self.attname, None))
+        setattr(cls, 'get_%s_value' % self.name, get_value)
+
+        def set_value(model_instance, json):
+            return setattr(model_instance, self.attname, dumps(json))
+        setattr(cls, 'set_%s_value' % self.name, set_value)
 
 
 class JQueryAutoCompleteWidget(forms.TextInput):
index 7be0f82..0e0e98f 100644 (file)
@@ -173,7 +173,7 @@ class Book(models.Model):
             book_shelves = list(book.tags.filter(category='set'))
         
         book.title = book_info.title
-        book.extra_info = book_info.to_dict()
+        book.set_extra_info_value(book_info.to_dict())
         book._short_html = ''
         book.save()
         
index 1718d97..7870cba 100644 (file)
@@ -115,6 +115,7 @@ def book_detail(request, slug):
     book_children = book.children.all().order_by('parent_number')
     extra_where = 'catalogue_tag.category = "theme"'
     book_themes = models.Tag.objects.related_for_model(book_tag, models.Fragment, counts=True, extra={'where': [extra_where]})
+    extra_info = book.get_extra_info_value()
     
     form = forms.SearchForm()
     return render_to_response('catalogue/book_detail.html', locals(),
index 2f14576..07c72bc 100644 (file)
@@ -12,7 +12,7 @@
     </form>
     
     <div id="books-list">
-        <p>Na podstawie: {{ book.extra_info.source_name }}</p>
+        <p>Na podstawie: {{ extra_info.source_name }}</p>
         {% if book.has_description %}
             <div id="description">
                 {{ book.description|safe }}
@@ -90,8 +90,8 @@
                     <a href="{{ tag.get_absolute_url }}">{{ tag }}</a>
                     {% endfor %}
                 </li>
-                <li><a href="{{ book.extra_info.about }}">Lektura na wiki projektu</a></li>
-                <li><a href="{{ book.extra_info.source_url }}">Lektura w CBN Polona</a></li>
+                <li><a href="{{ extra_info.about }}">Lektura na wiki projektu</a></li>
+                <li><a href="{{ extra_info.source_url }}">Lektura w CBN Polona</a></li>
                 <li><a href="{{ book.xml_file.url }}">Kod źródłowy utworu (XML)</a></li>
             </ul>
         </div>