Flask - reason for view function mapping is overwr

2020-08-04 06:47发布

问题:

Why I get this error when tried to use rendering:

Traceback (most recent call last):
  File "d:\Projects\jara.md\backend\flask\__init__.py", line 31, in <module>
    @app.route('/update/<int:adv_id>', methods=['PUT'])
  File "c:\Python27\lib\site-packages\flask\app.py", line 1080, in decorator
    self.add_url_rule(rule, endpoint, f, **options)
  File "c:\Python27\lib\site-packages\flask\app.py", line 64, in wrapper_func
    return f(self, *args, **kwargs)
  File "c:\Python27\lib\site-packages\flask\app.py", line 1051, in add_url_rule
    'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: start

Code list is:

app = Flask(__name__)


@app.route('/add', methods=['POST'])
def add():
    return 'Add'


@app.route('/start/<int:adv_id>', methods=['PUT'])
def start(adv_id):
    return 'start'

### Rendering ###

@app.route('/add', methods=['GET'])
def add():
    return render_template('add.html')

if __name__ == "__main__":
    app.run()

As you can see I have two methods add() for GET and POST requests.

What does this message mean?

 self.add_url_rule(rule, endpoint, f, **options)

@app.route('/update/<int:adv_id>', methods=['PUT'])
def start(adv_id):
    return 'update'

回答1:

This is the issue:

@app.route('/update/<int:adv_id>', methods=['PUT'])
def start(adv_id):
    return 'update'

You view names should be unique. You can't have two flask view methods with the same name. Name start and add methods to something else which is unique.

[Edit]

As @Oleg asked/commented that this unique name is a disadvantage. The reason for this is clear if you read the source code of Flask. From the source code

"""
Basically this example::
    @app.route('/')
    def index():
        pass Is equivalent to the following::

    def index():
        pass

    app.add_url_rule('/', 'index', index)

If the view_func is not provided you will need to connect the endpoint to a view function like so::

    app.view_functions['index'] = index
"""

So flask maps URL rule with the name of view function. in @app.route you are not passing a name so flask takes the method name creates the rule from it. Since this map is a dictionary it needs to be unique.

So, you can have view function with the same names(which you shouldn't as long as you pass the different name for the view)