AssertionError:视图函数映射覆盖现有端点函数:main

时间:2013-06-23 00:21:29

标签: python flask

如果我有两个这样的网址规则

,有谁知道为什么我不能覆盖现有的端点功能
app.add_url_rule('/',
                 view_func=Main.as_view('main'),
                 methods=["GET"])

app.add_url_rule('/<page>/',
                 view_func=Main.as_view('main'),
                 methods=["GET"])

回溯:

Traceback (most recent call last): 
  File "demo.py", line 20, in <module> methods=["GET"]) 
  File ".../python2.6/site-packages/flask‌​/app.py", 
    line 62, in wrapper_func return f(self, *args, **kwargs) 
  File ".../python2.6/site-packages/flask‌​/app.py", 
    line 984, in add_url_rule 'existing endpoint function: %s' % endpoint)  
AssertionError: View function mapping is overwriting an existing endpoint 
    function: main

12 个答案:

答案 0 :(得分:51)

同样的问题发生在我身上,但使用方法不同。当我尝试用2个装饰器包装API函数时:

  1. @ app.route()
  2. 我的服装@exception_handler decorator
  3. 我得到了同样的异常,因为我试图用这两个装饰器包装多个函数:

    @app.route("/path1")
    @exception_handler
    def func1():
        pass
    
    @app.route("/path2")
    @exception_handler
    def func2():
        pass
    

    具体来说,这是因为尝试使用名称包装注册一些函数引起的:

    def exception_handler(func):
      def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            error_code = getattr(e, "code", 500)
            logger.exception("Service exception: %s", e)
            r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code})
            return Response(r, status=error_code, mimetype='application/json')
      return wrapper
    

    更改函数名称为我解决了它( wrapper.func_name = func.func_name ):

    def exception_handler(func):
      def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            error_code = getattr(e, "code", 500)
            logger.exception("Service exception: %s", e)
            r = dict_to_json({"message": e.message, "matches": e.message, "error_code": error_code})
            return Response(r, status=error_code, mimetype='application/json')
      # Renaming the function name:
      wrapper.func_name = func.func_name
      return wrapper
    

    然后,装饰多个端点。

答案 1 :(得分:44)

即使视图名称指向相同的视图方法,您的视图名称也必须是唯一的。

app.add_url_rule('/',
                 view_func=Main.as_view('main'),
                 methods = ['GET'])

app.add_url_rule('/<page>/',
                 view_func=Main.as_view('page'),
                 methods = ['GET'])

答案 2 :(得分:14)

对于使用@ app.route的用户,最好使用密钥参数endpoint,而不是像Roei Bahumi那样查看__name__的值。以他的榜样为例:

@app.route("/path1", endpoint='func1')
@exception_handler
def func1():
    pass

@app.route("/path2", endpoint='func2')
@exception_handler
def func2():
    pass

答案 3 :(得分:8)

Flask要求您将单个“视图函数”与“端点”相关联。您正在调用Main.as_view('main')两次,这会创建两个不同的功能(功能完全相同但内存签名不同)。简短的故事,你应该简单地做

main_view_func = Main.as_view('main')

app.add_url_rule('/',
             view_func=main_view_func,
             methods=["GET"])

app.add_url_rule('/<page>/',
             view_func=main_view_func,
             methods=["GET"])

答案 4 :(得分:4)

我想在此添加一个更多的模板&#39;类型解决方案。

def func_name(f):
    def wrap(*args, **kwargs):
        if condition:
            pass
        else:
            whatever you want
        return f(*args, **kwargs)
    wrap.__name__ = f.__name__
    return wrap

只想添加一篇非常有趣的文章&#34; Demystifying Decorators&#34;我最近发现:https://sumit-ghosh.com/articles/demystifying-decorators-python/

答案 5 :(得分:2)

如果您认为自己拥有唯一的端点名称,但仍然会出现此错误,那么您可能面临issue。我的情况也是如此。

如果你有相同的版本,这个问题是烧瓶0.10,然后按照以下方法去掉:

sudo pip uninstall flask
sudo pip install flask=0.9

答案 6 :(得分:1)

Flask问题#570引入了近期(烧瓶0.10),导致引发此异常。

请参阅https://github.com/mitsuhiko/flask/issues/796

因此,如果你去flask / app.py并注释掉4行948..951,这可能会有所帮助,直到问题在新版本中完全恢复。

这种变化的差异在于:http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1

答案 7 :(得分:0)

即使您的视图名称指向相同的视图方法,也必须是唯一的,或者您可以从functools导入包装中添加并使用@wraps https://docs.python.org/2/library/functools.html

答案 8 :(得分:0)

改为使用烧瓶0.9 使用以下命令 sudo pip uninstall flask

sudo pip install flask==0.9

答案 9 :(得分:0)

当您在不同的路由上具有相同的函数名称时,也会发生这种情况。

答案 10 :(得分:0)

在包装函数上方添加@wraps(f)解决了我的问题。

def list_ownership(f):
    @wraps(f)
    def decorator(*args,**kwargs):
        return f(args,kwargs)
    return decorator

答案 11 :(得分:0)

如果你在python notebook上使用flask,每次修改代码都需要重启内核