Repository: girder/girder
Issue: RTD build has been failing for a while

The following command is causing a timeout because it's attempting to connect to mongo at localhost:27017.

```
python /home/docs/checkouts/readthedocs.org/user_builds/girder/envs/latest/bin/sphinx-build -T -E -b readthedocs -d _build/doctrees-readthedocs -D language=en . _build/html
```

The error output:

```
/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/docs/api-docs.rst:149: WARNING: autodoc: failed to import module u'girder.api.api_main'; the following exception was raised:
Traceback (most recent call last):
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/envs/latest/local/lib/python2.7/site-packages/sphinx/ext/autodoc.py", line 385, in import_object
    __import__(self.modname)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/api/api_main.py", line 23, in <module>
    from .v1 import assetstore, file, collection, folder, group, item, resource,\\
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/api/v1/file.py", line 31, in <module>
    class File(Resource):
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/api/v1/file.py", line 211, in File
    @loadmodel(model='file', level=AccessType.READ)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/api/rest.py", line 233, in __init__
    self.model = ModelImporter.model(model, plugin)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/utility/model_importer.py", line 93, in model
    _loadModel(model, module, plugin)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/utility/model_importer.py", line 47, in _loadModel
    _modelInstances[plugin][model] = constructor()
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/models/model_base.py", line 61, in __init__
    self.reconnect()
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/models/model_base.py", line 76, in reconnect
    self.collection.create_index(index)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/checkouts/latest/girder/external/mongodb_proxy.py", line 83, in __call__
    return self.method(*args, **kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/envs/latest/local/lib/python2.7/site-packages/pymongo/collection.py", line 1163, in create_index
    self.__create_index(keys, kwargs)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/envs/latest/local/lib/python2.7/site-packages/pymongo/collection.py", line 1074, in __create_index
    with self._socket_for_writes() as sock_info:
  File "/usr/lib/python2.7/contextlib.py", line 17, in __enter__
    return self.gen.next()
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/envs/latest/local/lib/python2.7/site-packages/pymongo/mongo_client.py", line 663, in _get_socket
    server = self._get_topology().select_server(selector)
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/envs/latest/local/lib/python2.7/site-packages/pymongo/topology.py", line 121, in select_server
    address))
  File "/home/docs/checkouts/readthedocs.org/user_builds/girder/envs/latest/local/lib/python2.7/site-packages/pymongo/topology.py", line 97, in select_servers
    self._error_message(selector))
ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused
```


Changed files:
girder/api/rest.py

diff --git a/girder/api/rest.py b/girder/api/rest.py
index 156f39c26..9632d8624 100644
--- a/girder/api/rest.py
+++ b/girder/api/rest.py
@@ -203,7 +203,7 @@ def getBodyJson():
         raise RestException('Invalid JSON passed in request body.')
 
 
-class loadmodel(object):
+class loadmodel(ModelImporter):
     """
     This is a decorator that can be used to load a model based on an ID param.
     For access controlled models, it will check authorization for the current
@@ -230,9 +230,10 @@ class loadmodel(object):
         else:
             self.map = map
 
-        self.model = ModelImporter.model(model, plugin)
         self.level = level
         self.force = force
+        self.modelName = model
+        self.plugin = plugin
 
     def _getIdValue(self, kwargs, idParam):
         if idParam in kwargs:
@@ -245,20 +246,22 @@ class loadmodel(object):
     def __call__(self, fun):
         @six.wraps(fun)
         def wrapped(*args, **kwargs):
+            model = self.model(self.modelName, self.plugin)
+
             for raw, converted in six.viewitems(self.map):
                 id = self._getIdValue(kwargs, raw)
 
                 if self.force:
-                    kwargs[converted] = self.model.load(id, force=True)
+                    kwargs[converted] = model.load(id, force=True)
                 elif self.level is not None:
-                    kwargs[converted] = self.model.load(
+                    kwargs[converted] = model.load(
                         id=id, level=self.level, user=getCurrentUser())
                 else:
-                    kwargs[converted] = self.model.load(id)
+                    kwargs[converted] = model.load(id)
 
                 if kwargs[converted] is None:
-                    raise RestException('Invalid {} id ({}).'
-                                        .format(self.model.name, id))
+                    raise RestException(
+                        'Invalid %s id (%s).' % (model.name, str(id)))
 
             return fun(*args, **kwargs)
         return wrapped