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

时间:2022-11-01 20:23:54

Does anyone know why I can't overwrite an existing endpoint function if i have two url rules like this

有没有人知道为什么我不能覆盖现有的端点函数,如果我有这样的两个网址规则

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:

追溯:

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

7 个解决方案

#1


34  

Your view names need to be unique even if they are pointing to the same view method.

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

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


29  

This same issue happen to me but with a different usage. When I tried to wrap an API function with 2 decorators:

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

  1. @app.route()
  2. @ app.route()
  3. My costume @exception_handler decorator
  4. 我的服装@exception_handler装饰

I got this same exception because I tried to wrap more than one function with those two decorators:

我得到了同样的异常,因为我试图用这两个装饰器包装多个函数:

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

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

Specifically, it is caused by trying to register a few functions with the name wrapper:

具体来说,它是通过尝试使用名称包装器注册一些函数引起的:

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

Changing the name of the function solved it for me (wrapper.func_name = func.func_name):

更改函数的名称为我解决了它(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

Then, decorating more than one endpoint worked.

然后,装饰多个端点工作。

#3


7  

For users that use @app.route it is better to use the key-argument endpoint rather then chaning the value of __name__ like Roei Bahumi stated. Taking his example will be:

对于使用@ app.route的用户,最好使用key-argument endpoint而不是像Roei Bahumi所说的那样修改__name__的值。以他的榜样为例:

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

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

#4


4  

Flask requires you to associate a single 'view function' with an 'endpoint'. You are calling Main.as_view('main') twice which creates two different functions (exactly the same functionality but different in memory signature). Short story, you should simply do

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"])

#5


1  

There is a fix for Flask issue #570 introduced recenty (flask 0.10) that causes this exception to be raised.

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

See https://github.com/mitsuhiko/flask/issues/796

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

So if you go to flask/app.py and comment out the 4 lines 948..951, this may help until the issue is resovled fully in a new version.

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

The diff of that change is here: http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1

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

#6


1  

If you think you have unique endpoint names and still this error is given then probably you are facing issue. Same was the case with me.

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

This issue is with flask 0.10 in case you have same version then do following to get rid of this:

这个问题是烧瓶0.10,如果你有相同的版本,然后做以下来摆脱这个:

sudo pip uninstall flask
sudo pip install flask=0.9

#7


0  

I would just like to add to this a more 'template' type solution.

我只想添加一个更“模板”类型的解决方案。

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

#1


34  

Your view names need to be unique even if they are pointing to the same view method.

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

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


29  

This same issue happen to me but with a different usage. When I tried to wrap an API function with 2 decorators:

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

  1. @app.route()
  2. @ app.route()
  3. My costume @exception_handler decorator
  4. 我的服装@exception_handler装饰

I got this same exception because I tried to wrap more than one function with those two decorators:

我得到了同样的异常,因为我试图用这两个装饰器包装多个函数:

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

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

Specifically, it is caused by trying to register a few functions with the name wrapper:

具体来说,它是通过尝试使用名称包装器注册一些函数引起的:

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

Changing the name of the function solved it for me (wrapper.func_name = func.func_name):

更改函数的名称为我解决了它(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

Then, decorating more than one endpoint worked.

然后,装饰多个端点工作。

#3


7  

For users that use @app.route it is better to use the key-argument endpoint rather then chaning the value of __name__ like Roei Bahumi stated. Taking his example will be:

对于使用@ app.route的用户,最好使用key-argument endpoint而不是像Roei Bahumi所说的那样修改__name__的值。以他的榜样为例:

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

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

#4


4  

Flask requires you to associate a single 'view function' with an 'endpoint'. You are calling Main.as_view('main') twice which creates two different functions (exactly the same functionality but different in memory signature). Short story, you should simply do

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"])

#5


1  

There is a fix for Flask issue #570 introduced recenty (flask 0.10) that causes this exception to be raised.

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

See https://github.com/mitsuhiko/flask/issues/796

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

So if you go to flask/app.py and comment out the 4 lines 948..951, this may help until the issue is resovled fully in a new version.

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

The diff of that change is here: http://github.com/mitsuhiko/flask/commit/661ee54bc2bc1ea0763ac9c226f8e14bb0beb5b1

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

#6


1  

If you think you have unique endpoint names and still this error is given then probably you are facing issue. Same was the case with me.

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

This issue is with flask 0.10 in case you have same version then do following to get rid of this:

这个问题是烧瓶0.10,如果你有相同的版本,然后做以下来摆脱这个:

sudo pip uninstall flask
sudo pip install flask=0.9

#7


0  

I would just like to add to this a more 'template' type solution.

我只想添加一个更“模板”类型的解决方案。

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