Reputation: 6544
In views
I have:
def cars(request, cars_id):
try:
car = Car.objects.filter(id=cars_id).values('model')
all_cars = Models.objects.filter(cars_id=cars_id).values('id',
'name', 'cars_id')
except Car.DoesNotExist:
cars_id=1
except Exception, e:
print e
except IndexError:
cars_id=1
return render_to_response('cars.html', {'all_cars': all_cars, 'car':car[0]['model']})
So, in browser I enter, for example, car/10000000/, and I have an error:
IndexError: list index out of range.
Why my 'except' doesnt work and how to fix it?
Upvotes: 0
Views: 3023
Reputation: 9359
1) learn about Exceptions hiearchy: If there's except
block of Exception first and IndexError later, IndexError is never catched, because it's child class of Exception (see
http://docs.python.org/library/exceptions.html#exception-hierarchy)
2) filter()
never raises DoesNotExist
exception, you have to check if there's some record in obtained QuerySet
.
3) your problem is zero index in return
line.
4) code should possibly looks like this:
def cars(request, cars_id):
try:
car = Car.objects.get(id=cars_id)
except Car.DoesNotExist:
#anyway - are you sure Car w/ id always exists?
car = Car.objects.all()[:1] #get first car
all_cars = Models.objects.filter(cars_id=cars_id).values('id', 'name', 'cars_id')
return render_to_response('cars.html', {'all_cars': all_cars, 'car':car.model})
Upvotes: 0
Reputation: 174622
Your problem is in the last line car[0]['model']
. When you don't have a car with the specified cars_id
, the car
list is empty, so you get an IndexError
. The fix is to get a default car when the car requested doesn't exist - the default car is id = 1
.
However, your all_cars
is the same as your car
line, except it contains extra fields. In other words, all_cars
will have one car or zero cars when cars_id
is invalid.
So its better to have all_cars
be a listing of all cars in your database:
def cars(request, cars_id):
all_cars = Models.objects.all().values('id',
'name', 'cars_id')
car = Car.objects.filter(id=cars_id).values('model')
if not car:
car = Car.objects.filter(id=1).values('model')
return render_to_response('cars.html', {'all_cars': all_cars,
'car':car[0]['model']})
Upvotes: 1
Reputation: 14783
I guess that your IndexError is thrown at an other location. For testing purposes try to wrap your entire view in a generic try catch block.
try:
car = Car.objects.filter(id=cars_id).values('model')
#include here all the other stuff you are doing
except Exception, e
print e
Your view - rewrote:
def cars(request, cars_id):
#to see whether you passed cars_id correctly
print "cars_id is"
print cars_id
all_cars = Models.objects.filter(cars_id=cars_id).values('id',
'name', 'cars_id')
try:
car = Car.objects.get(id=cars_id).values('model')
except Car.DoesNotExist:
print "the car for the given ID does not exist
#just return the "entire" car object in the context of the response.
#in the template you can then access car.model
return render_to_response('cars.html', {'all_cars': all_cars, 'car':car})
Upvotes: 0
Reputation: 5864
If you want to catch object existence, I recomend you to use DoesNotExist exception
def cars(request, cars_id):
try:
car = Car.objects.get(id=cars_id).values('model')
except Car.DoesNotExist:
#other stuff
According to your updated question: you are trying to get first item of None
. You should get car model for return in your try/except statement.
Upvotes: 2