librelist archives

« back to archive

[PATCH 0 of 2] Description

[PATCH 0 of 2] Description

From:
Mikhail Krivushin
Date:
2010-08-18 @ 12:17
Add svarga/core/description

[PATCH 2 of 2] Description fixes

From:
Mikhail Krivushin
Date:
2010-08-18 @ 12:17
# HG changeset patch
# User Mikhail Krivushin <krivushinme@gmail.com>
# Date 1282133813 -14400
# Node ID 4ebbbbf8433c461ca15f09ebc4a67a7d4dd4d3e5
# Parent  595cd631b2db51a244051d9ca0e5d0807364af83
Description fixes

diff -r 595cd631b2db -r 4ebbbbf8433c svarga/core/description.py
--- a/svarga/core/description.py	Wed Aug 18 02:04:27 2010 +0400
+++ b/svarga/core/description.py	Wed Aug 18 16:16:53 2010 +0400
@@ -1,55 +1,60 @@
+import types
 from copy import deepcopy
 
-class MetaDescription(type):
-    def __new__(cls, classname, bases, fields):
-        fs = {}
+from svarga.core.metadata import create_metadata
+
+
+class DescriptionType(type):
+    def __new__(cls, classname, bases, attrs):
+        create_metadata(cls, bases, attrs)
+
+        fields = {}
         meta = None
-        for k, v in fields.iteritems():
-            if isinstance(v, dict)  or k == 'get_desc':
-                fs[k] = v
-            elif k.startswith('__'):
-                continue
-            elif k == 'Meta':
+        for k, v in attrs.iteritems():
+            if k == 'Meta':
                 meta = v
-            else:
-                fs[k] = dict((k, v) for k, v in v.__dict__.items()
-                        if not k.startswith('_'))
-              
-        desc_type = type.__new__(cls, classname, bases, fs)
+            elif hasattr(v, '__dict__') and not isinstance(v, 
types.FunctionType):
+                v.get = classmethod(lambda v_cls, key, default:
+                                        getattr(v_cls, key, default))
+            fields[k] = v
+
+        desc_type = type.__new__(cls, classname, bases, fields)
 
         target = getattr(meta, 'target', None)
         if target:
             if not hasattr(target, 'Meta'):
                 target.Meta = type('Meta', (object,), {})
             target.Meta._description = desc_type
-        # else: type is not descript any object, but can be an ancestor
+        # else: this description has no target, but can be used as an ancestor
 
         return desc_type
 
 
 class Description(object):
-    __metaclass__ = MetaDescription
+    __metaclass__ = DescriptionType
 
     @classmethod
     def get_desc(cls, attr_name, desc_name, default=None):
-        if hasattr(cls, attr_name):
-            return getattr(cls, attr_name, {}).get(desc_name, default)
-        else:
-            return default
+        return getattr(cls, attr_name, {}).get(desc_name, default)
 
 
 def get_description(target):
     if not hasattr(target, 'Meta'):
-        target.Meta = type('Meta', (object,), {})
+        AttributeError('Description class works only with objects with 
associated Meta class.')
 
     if not hasattr(target.Meta, '_description'):
-        desc = Description()
+        attrs = {}
         for base in target.mro():
-            d = getattr( getattr(base, 'Meta', None), '_description', None)
-            if d:
-                desc = d
+            desc = getattr( getattr(base, 'Meta', None), '_description', None)
+            if desc:
+                attrs = dict([(k, deepcopy(v)) 
+                        for k, v in desc.__dict__.items() if not 
k.startswith('_')])
                 break
-        target.Meta._description = deepcopy(desc)
+
+        bases = (Description, )
+        target.Meta._description = type(target.__name__ + 'Description',
+                                                    bases, attrs)
+
     return target.Meta._description
 
 

[PATCH 1 of 2] Add descriptions and modify modelform

From:
Mikhail Krivushin
Date:
2010-08-18 @ 12:17
# HG changeset patch
# User Mikhail Krivushin <krivushinme@gmail.com>
# Date 1282082667 -14400
# Node ID 595cd631b2db51a244051d9ca0e5d0807364af83
# Parent  7766825dec00429e374ede30de28cc3c32c171e9
Add descriptions and modify modelform

diff -r 7766825dec00 -r 595cd631b2db svarga/core/description.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svarga/core/description.py	Wed Aug 18 02:04:27 2010 +0400
@@ -0,0 +1,55 @@
+from copy import deepcopy
+
+class MetaDescription(type):
+    def __new__(cls, classname, bases, fields):
+        fs = {}
+        meta = None
+        for k, v in fields.iteritems():
+            if isinstance(v, dict)  or k == 'get_desc':
+                fs[k] = v
+            elif k.startswith('__'):
+                continue
+            elif k == 'Meta':
+                meta = v
+            else:
+                fs[k] = dict((k, v) for k, v in v.__dict__.items()
+                        if not k.startswith('_'))
+              
+        desc_type = type.__new__(cls, classname, bases, fs)
+
+        target = getattr(meta, 'target', None)
+        if target:
+            if not hasattr(target, 'Meta'):
+                target.Meta = type('Meta', (object,), {})
+            target.Meta._description = desc_type
+        # else: type is not descript any object, but can be an ancestor
+
+        return desc_type
+
+
+class Description(object):
+    __metaclass__ = MetaDescription
+
+    @classmethod
+    def get_desc(cls, attr_name, desc_name, default=None):
+        if hasattr(cls, attr_name):
+            return getattr(cls, attr_name, {}).get(desc_name, default)
+        else:
+            return default
+
+
+def get_description(target):
+    if not hasattr(target, 'Meta'):
+        target.Meta = type('Meta', (object,), {})
+
+    if not hasattr(target.Meta, '_description'):
+        desc = Description()
+        for base in target.mro():
+            d = getattr( getattr(base, 'Meta', None), '_description', None)
+            if d:
+                desc = d
+                break
+        target.Meta._description = deepcopy(desc)
+    return target.Meta._description
+
+
diff -r 7766825dec00 -r 595cd631b2db svarga/forms/model.py
--- a/svarga/forms/model.py	Wed Aug 18 02:02:40 2010 +0400
+++ b/svarga/forms/model.py	Wed Aug 18 02:04:27 2010 +0400
@@ -4,6 +4,7 @@
 from wtforms.widgets import html_params
 
 from svarga.core.metadata import create_metadata
+from svarga.core.description import get_description
 from svarga.utils.imports import import_attribute
 
 __all__ = ['ModelForm', 'ForeignKeyField', 'MultiForeignKeyField']
@@ -240,8 +241,8 @@
 
                 if not f.foreign_key and not f.primary_key and n not in fields:
                     # Try locating field label in model's Meta
-                    label = getattr(model.Meta, 'description', {}
-                                    ).get(n, f.name)
+                    label = get_description(model).get_desc(f.name,
+                                    'verbose_name', f.name)
 
                     # Create new field
                     new_field = converter.convert(f, label)