I’m using Django 1.4 with Python 2.7 on Ubuntu 12.04.
I have a view that gets information from a form post. The first thing it does is tries to find the client information based on the information given in the form.
While testing I’m putting in bogus information and it seems to be OK with that. I’m expecting it to throw a DoesNotExist exception then I’m calling the original view to present the user with the form again. Can I not do that?
Here are the two views:
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)
And the original view that presents the form:
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)
I expect that the clientInfo = ClientInfo.objects.get(tkz_api_id = tkz_ys_api_id, tkz_trans_key = tkz_ys_trans_key) request in input_new_client would throw a DoesNotExist exception (as I put in fake data to ensure this to be the case).
So, I was just going to call the add_new_client view from within the exception.
The problem is that the input_new_client gets all the way down to the new_client.save() line, which fails for obvious reasons.
Any thoughts?
EDIT1:
I’ve modified the input_new_client view to have the following exception statement:
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)
I know it gets into the exception – I can verify with log info and the traceback. However, it does not go on to add_new_client. It instead skips along ahead and tries to insert a new entry in the ClientInfo model with incorrect data.
Why is it skipping the call to add_new_client?
This line:
doesn’t do what you think it does. The
oris evaluated first, so in effect (I think) this is just trying to catch an exception of typeTrue, which of course is never raised. What you actually want is this:(note the parentheses).
Also note that the bare
exceptclause in your second snippet is a very bad idea: it will catch all exceptions, so if something goes wrong that you weren’t expecting, you’ll never know about it. Make sure you only catch the handling errors that your except clause knows how to deal with.Edit
Ah, I see what you’re doing now – you’re trying to return a response to the user from inside the exception. Well, there’s nothing wrong with that specifically, except that you don’t actually send it back to the user: you just call
add_new_client(), and don’t do anything with the HTTP response that’s sent back. You need to actually return it to the user from there: