Python / Django - 列出索引超出范围的函数

时间:2016-07-01 14:25:33

标签: python django

我有一个获取用户历史记录并将其放在面包屑中的功能,我试图通过显示来使面包屑看起来更好。所以我的函数应该能够返回一个很好的可读URL而不是/ service / site / 7它会将“Site UK”或“Showroom - Italy”作为面包屑。

然而,只要我没有(我推测)足够的项目加载页面,我就会收到错误“异常值:列表索引超出范围”

我想通过使用“if list_path [1]:”如果该项目不存在则会返回false,但它仍然会给我错误。

我也试过使用if“list_path [0]> 0”和“if list_path [0]> 1”它使一些页面加载但其他人失败并出现同样的错误。

我认为这是因为它存储4个值并且每次都在所有四个值上运行脚本?

由于

代码:

def breadcrumb_history(request):
    history = request.session.get('breadcrumb_history', [])

    # if the last item in the history is the current page, we don't want to add this page to the history
    # if it's not the last item in the history, we do add it
    if len(history) == 0 or history[-1] != request.path:
        url = request.path
        display = ''
        list_path = url.split("/")
        list_path = filter(None,list_path)
        if list_path[0]:
            if list_path[0] != "admin":
                del list_path[0]
        if list_path[1]:
            if list_path[1] == "majorsite":
                list_path[1] = "Major Site"
                site = MajorSiteInfoData.object.values("location").get(pk=list_path[2])
                list_path[2] = site.location
            elif list_path[1] == "showroom":
                showroom = ShowroomConfigData.object.values("location").get(pk=list_path[2])
                list_path[2] = showroom.location

            display = ''.join(list_path)
            display = display.title()
        else:
            display = url.title()
        history.append({"url" : url, "display" : display})

    # if there are more than four items in the history, pop the first one
    if len(history) > 4:
        history.pop(0)

    # save the history to the session
    request.session['breadcrumb_history'] = history

    # return the current breadcrumb
    return {'breadcrumb_history': history}

回溯:

Environment:


Request Method: GET
Request URL: http://it.internal.com/service/showrooms

Django Version: 1.9.6
Python Version: 2.7.5
Installed Applications:
('home.apps.HomeConfig',
 'oncall.apps.OncallConfig',
 'networks.apps.NetworksConfig',
 'maintenance.apps.MaintenanceConfig',
 'service.apps.ServiceConfig',
 'management.apps.ManagementConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'debug_toolbar',
 'twitter_bootstrap',
 'bootstrap_pagination')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware')



Traceback:

File "/usr/lib64/python2.7/site-packages/django/core/handlers/base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "/usr/lib64/python2.7/site-packages/django/core/handlers/base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/lib64/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/var/www/infternal/service/views.py" in showroom_list
  41.         'Showrooms': modelShowrooms,

File "/usr/lib64/python2.7/site-packages/django/shortcuts.py" in render
  67.             template_name, context, request=request, using=using)

File "/usr/lib64/python2.7/site-packages/django/template/loader.py" in render_to_string
  97.         return template.render(context, request)

File "/usr/lib64/python2.7/site-packages/django/template/backends/django.py" in render
  95.             return self.template.render(context)

File "/usr/lib64/python2.7/site-packages/django/template/base.py" in render
  204.                 with context.bind_template(self):

File "/usr/lib64/python2.7/contextlib.py" in __enter__
  17.             return self.gen.next()

File "/usr/lib/python2.7/site-packages/debug_toolbar/panels/templates/panel.py" in _request_context_bind_template
  79.             context = processor(self.request)

File "/var/www/infternal/infternal/context_processors.py" in breadcrumb_history
  52.         if list_path[1]:

Exception Type: IndexError at /service/showrooms
Exception Value: list index out of range

编辑: 示例URLS包括:

/ (this would be replaced with home)
/majorsite/2 (replaced with "Major Site - HQ" or "Major Site - Warehouse")
/showroom/7 (replaced with "Showroom - London" or "Showroom - Manchester")

3 个答案:

答案 0 :(得分:0)

if list_path[0]:
    if list_path[0] != "admin":
        del list_path[0]  # Here you delete the first element of the list.
                          # Thus `list_path` now equals `['showrooms']`.
                          # and `list_path[1]` doesn't exist anymore.

答案 1 :(得分:0)

似乎并非总是您的网址符合您的预期,有时您的list_path中不会包含多个项目,这可能会因/majorsite/admin之类的路径而发生等等......因此,在更安全的解决方案下进行更换可能更准确:

to_replace = ['majorsite', ...]
replace_with = ['Major Site', ...]

for item in zip(to_replace,replace_with):
    if item[0] in list_path:
        # replace item[0] by item[1] in list_path, since you are sure it is there
        # add additional customizations

这显然是一种替代方案,您可以按照自己的方式进行操作,但在这种情况下,您需要确保在每种情况下,数组在请求索引之前都具有预期的长度,而且,要替换的术语是有:

if len(list_path)>1 and list_path[1]:
    # what you do today
else:
    # handle other cases

另外,你的代码有点复杂,我几乎可以肯定有一种简单的方法可以实现你想要的。如果您添加一些可以处理的所有可能网址的样本,以及每种情况下的预期结果,您将在此处获得一些简单的答案。

答案 2 :(得分:-3)

你应该使用

try: 
    ...
expect IndexError:
    # Handle exception

list_path什么都没有