flask-marshmallow icon indicating copy to clipboard operation
flask-marshmallow copied to clipboard

AbsoluteURLFor: Field parameters are passed to URL

Open floqqi opened this issue 7 years ago • 1 comments

I use AbsoluteURLFor for generating an URL to an image:

from flask_marshmallow import Marshmallow
from flask_marshmallow.fields import AbsoluteURLFor
from marshmallow import fields

ma = Marshmallow()

class TestSchema(ma.Schema):
    my_logo = AbsoluteURLFor(
        'logo_api',  # /api/logos/<id>
        id='<logo_id>',
        dump_to='myLogo'
    )

The resulting response is:

{
  "myLogo": "http://localhost:5000/api/logos/1?dump_to=myLogo"
}

The expected result is:

{
  "myLogo": "http://localhost:5000/api/logos/1"
}

If I skip the dump_to-parameter the result is:

{
  "my_logo": "http://localhost:5000/api/logos/1"
}

This is because the field parameter dump_to is passed as a parameter to flask.url_for. But this is (of course) not my intention. Can this be fixed or do I have to use another field like Function for example?

floqqi avatar Aug 24 '17 08:08 floqqi

I ran into this same limitation or side effect as I wanted to add description to the Field class metadata. One work-around looked something like this:

    player_url = AbsoluteURLFor('players.entry', player_id='<player_id>')
    player_url.metadata['description'] = "Fully qualified URL of the player resource"

I wrote a wrapper for this particular case:

def Url(endpoint, **kwargs):
    """
    Returns AbsoluteURLFor field. If 'kwargs' contains 'doc' it will not be passed to
    AbsoluteURLFor but instead added to the metadata of the parent class as 'description'.
    """
    doc = kwargs.pop('doc')
    url = AbsoluteURLFor(endpoint, **kwargs)
    if doc:
        url.metadata['description'] = doc
    return url

One potential fix is to tag which parameters should not be forwarded to url_for by prefixing them with an underscore.

mattig avatar Oct 29 '18 10:10 mattig