0

我在 Ubuntu 12.04 上使用 Django 1.4 和 Python 2.7。

我有一个从表单帖子中获取信息的视图。它所做的第一件事是尝试根据表单中提供的信息查找客户信息。

在测试时,我输入了虚假信息,这似乎没问题。我期待它抛出一个DoesNotExist异常,然后我调用原始视图再次向用户展示表单。我不能那样做吗?

以下是两种观点:

def input_new_client(request):
    """
    ..  function:: input_new_client()

        Add the client based on the addClientInfo form

        :param request: Django Request object
    """
    ## Create a logging object
    path = os.path.join(os.path.dirname(__file__), 'logs/')
    filename = '{0}inputNewClient.log'.format(path)
    logfile = open(filename, 'w')
    now = datetime.datetime.now()
    logfile.write('\n --------------------- {0}\n'.format(now))

    if (request.method == "POST"):
        tkz_ys_api_id = request.POST.get("tkz_ys_api_id")
        tkz_ys_trans_key = request.POST.get("tkz_ys_trans_key")

        ## Validate the YS authentication information
        try:
            clientInfo = ClientInfo.objects.get(tkz_api_id = tkz_ys_api_id, tkz_trans_key = tkz_ys_trans_key)
        except ClientInfo.DoesNotExist or ClientInfo.MultipleObjectsReturned:
            logfile.write('{0}\n\n'.format(tkz_ys_api_id))
            logfile.write('{0}\n\n'.format(tkz_ys_trans_key))
            logfile.write('{0}\n\n'.format(traceback.format_exc()))
            logfile.close()
            state = "Invalid YS Authentication!  Please try again."
            add_new_client(request, state)
        else:
            if (clientInfo.name != "Your Solutions"):
                state = "Invalid YS Authentication!  Please try again."
                add_new_client(request, state)

        ## Generate a Tokeniz API ID and Trans Key for the new client
        (tkz_api_id, tkz_trans_key) = generate_credentials()

        ## Create a new client
        new_client = ClientInfo(name = request.POST.get("tkz_client_name"),
                                tkz_api_id = tkz_api_id,
                                tkz_trans_key = tkz_trans_key,
                                default_gateway_id = request.POST.get("tkz_gateway")
                               )
        new_client.save()

        ## Validate the YS authentication information
        try:
            clientInfo = ClientInfo.objects.get(tkz_api_id = tkz_api_id, tkz_trans_key = tkz_trans_key)
            foriegn_key = clientInfo.id
        except ClientInfo.DoesNotExist or ClientInfo.MultipleObjectsReturned:
            output = "Invalid YS Authentication!  Please try again."
            logfile.write('\n{0}\n'.format(output))
            logfile.write('{0}\n\n'.format(traceback.format_exc()))
            logfile.close()

        ## Setup the new clients gateway information
        new_gateway_info = GatewayInfo(client = foriegn_key,
                                       api_id = request.POST.get("tkz_gateway_api_id"),
                                       trans_key = request.POST.get("tkz_gateway_trans_key"),
                                       gateway_id = request.POST.get("tkz_gateway"),
                                      )
        new_gateway_info.save()

        data = {}
        data.update(csrf(request))
        data.update({ 'tkz_api_id' : tkz_api_id })
        data.update({ 'tkz_trans_key' : tkz_trans_key })
        data.update({ 'client_name' : request.POST.get("tkz_client_name")})

    return render_to_response("updatedClientCredentials.html", data)

以及呈现形式的原始视图:

def add_new_client(request, state = None):
    """
    ..  function:: add_new_client()

        Provide a form for entering new client information

        :param request: Django Request object
        :param state: A message representing the state of the addition of a client
    """
    ## Create a logging object
    path = os.path.join(os.path.dirname(__file__), 'logs/')
    filename = '{0}addNewClient.log'.format(path)
    logfile = open(filename, 'a')
    now = datetime.datetime.now()
    logfile.write('\n --------------------- {0}\n'.format(now))

    if (state is None):
        state = "Enter information for adding a new client to Tokeniz."

    try:
        form = AddClientInfo()
    except:
        output = "Handle Error: Cannot create a valid form"
        logfile.write('{0}\n'.format(output))
        logfile.write('{0}\n\n'.format(traceback.format_exc()))
        logfile.close()
        return HttpResponse(output)

    try:
        data = {}
        data.update(csrf(request))
        data.update({ 'form' : form })
        data.update({ 'state' : state })
    except:
        output = "Handle Error: Cannot generate CSRF token"
        logfile.write('{0}\n'.format(output))
        logfile.write('{0}\n\n'.format(traceback.format_exc()))
        logfile.close()
        return HttpResponse(output)

    logfile.close()
    return render_to_response("addNewClientInfo.html", data)

我希望clientInfo = ClientInfo.objects.get(tkz_api_id = tkz_ys_api_id, tkz_trans_key = tkz_ys_trans_key)请求input_new_client会引发DoesNotExist异常(因为我输入了假数据以确保情况如此)。

所以,我只是add_new_client要从异常中调用视图。

问题是input_new_client一直到new_client.save()线,由于明显的原因而失败。

有什么想法吗?

编辑1:

我已将input_new_client视图修改为具有以下异常语句:

if (request.method == "POST"):
    tkz_ys_api_id = request.POST.get("tkz_ys_api_id")
    tkz_ys_trans_key = request.POST.get("tkz_ys_trans_key")
    tkz_gateway_id = int(request.POST.get("tkz_gateway"))

    ## Validate the YS authentication information
    try:
        clientInfo = ClientInfo.objects.get(tkz_api_id = tkz_ys_api_id, tkz_trans_key = tkz_ys_trans_key)
    except (ClientInfo.DoesNotExist, ClientInfo.MultipleObjectsReturned):
        logfile.write('tkz_ys_api_id = {0}\n\n'.format(tkz_ys_api_id))
        logfile.write('tkz_ys_trans_key = {0}\n\n'.format(tkz_ys_trans_key))
        logfile.write('tkz_gateway_id = {0}\n\n'.format(tkz_gateway_id))
        logfile.write('{0}\n\n'.format(traceback.format_exc()))
        logfile.close()
        state = "Invalid YS Authentication!  Please try again."
        add_new_client(request, state)
    else:
        if (clientInfo.name != "Your Solutions"):
            state = "Invalid YS Authentication!  Please try again."
            add_new_client(request, state)

我知道它进入了异常 - 我可以使用日志信息和回溯进行验证。但是,它并没有继续下去add_new_client。相反,它会向前跳过并尝试在ClientInfo模型中插入一个包含不正确数据的新条目。

为什么它会跳过对 的调用add_new_client

4

1 回答 1

4

这一行:

except ClientInfo.DoesNotExist or ClientInfo.MultipleObjectsReturned:

不做你认为它做的事。Theor首先被评估,所以实际上(我认为)这只是试图捕捉 type 的异常True,当然它永远不会被引发。你真正想要的是这样的:

except (ClientInfo.DoesNotExist, ClientInfo.MultipleObjectsReturned):

(注意括号)。

另请注意,except第二个片段中的裸子句是一个非常糟糕的主意:它会捕获所有异常,因此如果出现您未预料到的错误,您将永远不会知道。确保您只捕获您的 except 子句知道如何处理的处理错误。

编辑

啊,我明白你现在在做什么——你正试图从异常内部向用户返回响应。好吧,这并没有什么特别的问题,只是您实际上并没有将其发送回用户:您只需调用add_new_client(),并且不对发回的 HTTP 响应做任何事情。您需要从那里实际将其返回给用户:

except (ClientInfo.DoesNotExist, ClientInfo.MultipleObjectsReturned):
    ... logging stuff ...
    state = "Invalid YS Authentication!  Please try again."
    return add_new_client(request, state)
于 2012-10-10T13:13:14.397 回答