diff --git a/HISTORY.rst b/HISTORY.rst
index 1b69669..d10faee 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -7,7 +7,14 @@ dev
 * ``missing`` attribute is no longer used in umongo fields, only ``default`` is
   used. ``marshmallow_missing`` and ``marshmallow_default`` attribute can be
   used to overwrite the value to use in the pure marshmallow field returned
-  by `as_marshmallow_field` method.
+  by ``as_marshmallow_field`` method.
+* ``as_marshmallow_field`` does not pass ``load_from``, ``dump_to`` and
+  ``attribute`` to the pure marshmallow field anymore. It only passes
+  ``validate``, ``required``, ``allow_none``, ``dump_only``, ``load_only`` and
+  ``error_messages``, as well as ``default`` and ``missing`` values inferred
+  from umongo's ``default``. Parameters prefixed with ``marshmallow_`` in the
+  umongo field are passed to the pure marshmallow field and override their
+  non-prefixed counterpart.
 
 1.2.0 (2019-02-08)
 ------------------
diff --git a/umongo/abstract.py b/umongo/abstract.py
index a8a1096..0778836 100644
--- a/umongo/abstract.py
+++ b/umongo/abstract.py
@@ -117,7 +117,29 @@ class BaseField(ma_fields.Field):
                 "generating pure Marshmallow field.")
         if 'default' in kwargs:
             kwargs['missing'] = kwargs['default']
+
+        # Store attributes prefixed with marshmallow_ to use them when
+        # creating pure marshmallow Schema
+        for attribute in (
+            'load_from', 'dump_to', 'attribute',
+            'validate', 'required', 'allow_none',
+            'load_only', 'dump_only', 'error_messages'
+        ):
+            attribute = 'marshmallow_' + attribute
+            if attribute in kwargs:
+                setattr(self, attribute, kwargs.pop(attribute))
+
+        # Infer from "default" parameter a default value for
+        # marshmallow_default and marshmallow_missing
+        def serialize_default():
+            val = self.default() if callable(self.default) else self.default
+            return self.serialize('foo', {'foo': val})
+
+        self.marshmallow_missing = kwargs.pop('marshmallow_missing', serialize_default)
+        self.marshmallow_default = kwargs.pop('marshmallow_default', serialize_default)
+
         super().__init__(*args, **kwargs)
+
         # Overwrite error_messages to handle i18n translation
         self.error_messages = I18nErrorDict(self.error_messages)
         # `io_validate` will be run after `io_validate_resursive`
@@ -128,13 +150,6 @@ class BaseField(ma_fields.Field):
         self.unique = unique
         self.instance = instance
 
-        def serialize_default():
-            val = self.default() if callable(self.default) else self.default
-            return self.serialize('foo', {'foo': val})
-
-        self.marshmallow_missing = kwargs.get('marshmallow_missing', serialize_default)
-        self.marshmallow_default = kwargs.get('marshmallow_default', serialize_default)
-
     def __repr__(self):
         return ('<fields.{ClassName}(default={self.default!r}, '
                 'attribute={self.attribute!r}, '
@@ -213,18 +228,26 @@ class BaseField(ma_fields.Field):
         return {self.attribute or key: query}
 
     def _extract_marshmallow_field_params(self, mongo_world):
-        params = {field: getattr(self, field)
-                  for field in ('load_from', 'validate', 'required',
-                                'allow_none', 'load_only',
-                                'dump_only', 'error_messages')}
+        params = {
+            attribute: getattr(self, attribute)
+            for attribute in (
+                'validate', 'required', 'allow_none',
+                'dump_only', 'load_only', 'error_messages'
+            )
+        }
         if mongo_world and self.attribute:
             params['attribute'] = self.attribute
-        # Marshmallow doesn't serialize default value when doing `dump`,
-        # hence we use the serialized value..
-        params['default'] = self.marshmallow_default
-        # ...on the other hand, marshmallow does use unserialize on the
-        # missing value when doing `load`, hence also use the serialized value
-        params['missing'] = self.marshmallow_missing
+
+        # Override uMongo attributes with marshmallow_ prefixed attributes
+        for attribute in (
+            'default', 'missing', 'load_from', 'dump_to', 'attribute',
+            'validate', 'required', 'allow_none',
+            'load_only', 'dump_only', 'error_messages'
+        ):
+            ma_attribute = 'marshmallow_' + attribute
+            if hasattr(self, ma_attribute):
+                params[attribute] = getattr(self, ma_attribute)
+
         params.update(self.metadata)
         return params
 

Rework  _extract_marshmallow_field_params
I think we should rework `_extract_marshmallow_field_params` to avoid copying `default`, `missing`, `load_from`, `dump_to` and perhaps other attributes.

Current version:

```py
    def _extract_marshmallow_field_params(self, mongo_world):
        params = {field: getattr(self, field)
                  for field in ('default', 'load_from', 'validate',
                                'required', 'allow_none', 'load_only',
                                'dump_only', 'missing', 'error_messages')}
        if mongo_world and self.attribute:
            params['attribute'] = self.attribute
        params.update(self.metadata)
        return params
```

This is partly addressed in https://github.com/Scille/umongo/pull/107 (only `default` and `missing` are dealt with).

Copying `load_from` seems like a mistake to me because it is used to map an OO world name to a Mongo name, so using it to map an outside world name to an OO world name is bound to fail. If we want to keep flexibility, we could do the same as in #107: add `marshmallow_load_from` attribute, maybe we could even blindly pass all attributes prefixed with `marshmallow_`.

We should finalize #107 and complete it to remove other attributes, at least `load_from` and `dump_to`, maybe others (feedback welcome).

Not sure when I'll get the time to do that.

FWIW, here's the monkeypatch I'm using in my code for now.

```py
def _extract_marshmallow_field_params(self, mongo_world):
    params = {field: getattr(self, field)
              for field in ('validate', 'required', 'allow_none',
                            'load_only', 'dump_only', 'error_messages')}
    if mongo_world and self.attribute:
        params['attribute'] = self.attribute
    params.update(self.metadata)
    return params
BaseField._extract_marshmallow_field_params = _extract_marshmallow_field_params
```

diff --git a/tests/test_marshmallow.py b/tests/test_marshmallow.py
index 919e8a8..f58aba4 100644
--- a/tests/test_marshmallow.py
+++ b/tests/test_marshmallow.py
@@ -133,6 +133,59 @@ class TestMarshmallow(BaseTest):
         assert ma_custom_base_schema.Meta.exclude == ('content',)
         assert ma_custom_base_schema.Meta.dump_only == ('id',)
 
+    def test_as_marshmallow_field_pass_params(self):
+        @self.instance.register
+        class MyDoc(Document):
+            lf = fields.IntField(marshmallow_load_from='lflf')
+            dt = fields.IntField(marshmallow_dump_to='dtdt')
+            at = fields.IntField(marshmallow_attribute='atat')
+            re = fields.IntField(marshmallow_required=True)
+            an = fields.IntField(marshmallow_allow_none=True)
+            lo = fields.IntField(marshmallow_load_only=True)
+            do = fields.IntField(marshmallow_dump_only=True)
+            va = fields.IntField(marshmallow_validate=validate.Range(min=0))
+            em = fields.IntField(marshmallow_error_messages={'invalid': 'Wrong'})
+
+        MyMaDoc = MyDoc.schema.as_marshmallow_schema()
+
+        assert MyMaDoc().fields['lf'].load_from == 'lflf'
+        assert MyMaDoc().fields['dt'].dump_to == 'dtdt'
+        assert MyMaDoc().fields['at'].attribute == 'atat'
+        assert MyMaDoc().fields['re'].required is True
+        assert MyMaDoc().fields['an'].allow_none is True
+        assert MyMaDoc().fields['lo'].load_only is True
+        assert MyMaDoc().fields['do'].dump_only is True
+        _, err = MyMaDoc().load({'va': -1})
+        assert 'va' in err
+        assert MyMaDoc().fields['em'].error_messages['invalid'] == 'Wrong'
+
+    def test_as_marshmallow_field_infer_missing_default(self):
+        @self.instance.register
+        class MyDoc(Document):
+            de = fields.IntField(default=42)
+            mm = fields.IntField(marshmallow_missing=12)
+            md = fields.IntField(marshmallow_default=12)
+            mmd = fields.IntField(default=42, marshmallow_missing=12)
+            mdd = fields.IntField(default=42, marshmallow_default=12)
+
+        MyMaDoc = MyDoc.schema.as_marshmallow_schema()
+
+        data, _ = MyMaDoc().load({})
+        assert data == {
+            'de': 42,
+            'mm': 12,
+            'mmd': 12,
+            'mdd': 42,
+        }
+
+        data, _ = MyMaDoc().dump({})
+        assert data == {
+            'de': 42,
+            'md': 12,
+            'mmd': 42,
+            'mdd': 12,
+        }
+
     def test_as_marshmallow_schema_cache(self):
         ma_schema_cls = self.User.schema.as_marshmallow_schema()
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.6
requirements_dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
attrs==22.2.0
Babel==2.11.0
bump2version==1.0.1
bumpversion==0.6.0
certifi==2021.5.30
charset-normalizer==2.0.12
coverage==6.2
distlib==0.3.9
docutils==0.17.1
filelock==3.4.1
flake8==5.0.4
idna==3.10
imagesize==1.4.1
importlib-metadata==4.2.0
importlib-resources==5.4.0
iniconfig==1.1.1
Jinja2==3.0.3
MarkupSafe==2.0.1
marshmallow==2.21.0
mccabe==0.7.0
packaging==21.3
platformdirs==2.4.0
pluggy==1.0.0
py==1.11.0
pycodestyle==2.9.1
pyflakes==2.5.0
Pygments==2.14.0
pymongo==4.1.1
pyparsing==3.1.4
pytest==7.0.1
pytest-cov==4.0.0
python-dateutil==2.9.0.post0
pytz==2025.2
requests==2.27.1
six==1.17.0
snowballstemmer==2.2.0
Sphinx==4.3.2
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
toml==0.10.2
tomli==1.2.3
tox==3.28.0
typing_extensions==4.1.1
-e git+https://github.com/Scille/umongo.git@3e765b3aa7250564c2eabddd1e776e6c806fa7fa#egg=umongo
urllib3==1.26.20
virtualenv==20.16.2
zipp==3.6.0

name: umongo
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - attrs==22.2.0
      - babel==2.11.0
      - bump2version==1.0.1
      - bumpversion==0.6.0
      - charset-normalizer==2.0.12
      - coverage==6.2
      - distlib==0.3.9
      - docutils==0.17.1
      - filelock==3.4.1
      - flake8==5.0.4
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.2.0
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - jinja2==3.0.3
      - markupsafe==2.0.1
      - marshmallow==2.21.0
      - mccabe==0.7.0
      - packaging==21.3
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - py==1.11.0
      - pycodestyle==2.9.1
      - pyflakes==2.5.0
      - pygments==2.14.0
      - pymongo==4.1.1
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-cov==4.0.0
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - requests==2.27.1
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==4.3.2
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - toml==0.10.2
      - tomli==1.2.3
      - tox==3.28.0
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - virtualenv==20.16.2
      - zipp==3.6.0
prefix: /opt/conda/envs/umongo

tests/test_marshmallow.py::TestMarshmallow::test_as_marshmallow_field_pass_params
tests/test_marshmallow.py::TestMarshmallow::test_by_field tests/test_marshmallow.py::TestMarshmallow::test_by_schema tests/test_marshmallow.py::TestMarshmallow::test_custom_base_schema tests/test_marshmallow.py::TestMarshmallow::test_customize_params tests/test_marshmallow.py::TestMarshmallow::test_customize_nested_and_container_params tests/test_marshmallow.py::TestMarshmallow::test_pass_meta_attributes tests/test_marshmallow.py::TestMarshmallow::test_as_marshmallow_field_infer_missing_default tests/test_marshmallow.py::TestMarshmallow::test_as_marshmallow_schema_cache tests/test_marshmallow.py::TestMarshmallow::test_keep_attributes tests/test_marshmallow.py::TestMarshmallow::test_keep_validators tests/test_marshmallow.py::TestMarshmallow::test_inheritance tests/test_marshmallow.py::TestMarshmallow::test_to_mongo tests/test_marshmallow.py::TestMarshmallow::test_i18n tests/test_marshmallow.py::TestMarshmallow::test_unknow_fields_check tests/test_marshmallow.py::TestMarshmallow::test_missing_accessor tests/test_marshmallow.py::TestMarshmallow::test_nested_field tests/test_marshmallow.py::TestMarshmallow::test_marshmallow_bonus_fields tests/test_marshmallow.py::TestMarshmallow::test_marshmallow_schema_helpers tests/test_marshmallow.py::TestMarshmallow::test_marshmallow_access_custom_attributes tests/test_marshmallow.py::TestMarshmallow::test_dump_only
HISTORY.rst umongo/abstract.py
HISTORY.rst umongo/abstract.py