Repository: flask-admin/flask-admin

Issue:
Import error trying to use sqlamodel
I'm unable to use the sqlamodel extension due to an import error. Please see below. Perhaps a packaging problem?

```
from flask.ext.adminex.ext.sqlamodel import ModelBase
```

  File "/Users/andy/.virtualenvs/marty/lib/python2.7/site-packages/flask/exthook.py", line 86, in load_module
    raise ImportError('No module named %s' % fullname)
ImportError: No module named flask.ext.adminex.ext



Discussion:
That's strange. Do you have MANIFEST.in in your local copy? As it should copy all child directories when you install the package.

Try pulling latest changes - I adjusted setup.py and MANIFEST.in slightly, so it is more compatible now. Hope it will help.

Hey I just ran into the same issue.

I found this to work:

```
from flask.ext.adminex.ext.sqlamodel import ModelView
```

I looked into the source code and got it to work.

Thanks for report, was typo in the documentation.

Ah, thanks. Will try this shortly and I expect it to work.


Resolving patch:
diff --git a/flask_admin/contrib/sqlamodel/form.py b/flask_admin/contrib/sqlamodel/form.py
--- a/flask_admin/contrib/sqlamodel/form.py
+++ b/flask_admin/contrib/sqlamodel/form.py
@@ -31,6 +31,12 @@ def _get_label(self, name, field_args):
 
         return None
 
+    def _get_description(self, name, field_args):
+        if 'description' in field_args:
+            return field_args['description']
+        if self.view.column_descriptions:
+            return self.view.column_descriptions.get(name)
+
     def _get_field_override(self, name):
         form_overrides = getattr(self.view, 'form_overrides', None)
 
@@ -54,6 +60,7 @@ def convert(self, model, mapper, prop, field_args, hidden_pk):
             local_column = prop.local_remote_pairs[0][0]
 
             kwargs['label'] = self._get_label(prop.key, kwargs)
+            kwargs['description'] = self._get_description(prop.key, kwargs)
 
             if local_column.nullable:
                 kwargs['validators'].append(validators.Optional())
@@ -135,8 +142,10 @@ def convert(self, model, mapper, prop, field_args, hidden_pk):
                 if not column.nullable and not isinstance(column.type, Boolean):
                     kwargs['validators'].append(validators.Required())
 
-                # Apply label
-                kwargs['label'] = self._get_label(prop.key, kwargs)
+                # Apply label and description if it isn't inline form field
+                if self.view.model == mapper.class_:
+                    kwargs['label'] = self._get_label(prop.key, kwargs)
+                    kwargs['description'] = self._get_description(prop.key, kwargs)
 
                 # Figure out default value
                 default = getattr(column, 'default', None)
diff --git a/flask_admin/model/base.py b/flask_admin/model/base.py
--- a/flask_admin/model/base.py
+++ b/flask_admin/model/base.py
@@ -129,6 +129,19 @@ class MyModelView(BaseModelView):
                 column_labels = dict(name='Name', last_name='Last Name')
     """
 
+    column_descriptions = None
+    """
+        Dictionary where key is column name and
+        value is description for `list view` column or add/edit form field.
+
+        For example::
+
+            class MyModelView(BaseModelView):
+                column_descriptions = dict(
+                    full_name='First and Last name'
+                )
+    """
+
     column_sortable_list = ObsoleteAttr('column_sortable_list',
                                         'sortable_columns',
                                         None)
@@ -324,6 +337,9 @@ def _refresh_cache(self):
         if self.column_type_formatters is None:
             self.column_type_formatters = dict(typefmt.DEFAULT_FORMATTERS)
 
+        if self.column_descriptions is None:
+            self.column_descriptions = dict()
+
         if self._filters:
             self._filter_groups = []
             self._filter_dict = dict()


Test patch: