django objects.get() does not find result
Asked Answered
E

3

5

quick question. I run the following code with a try except statement (as it is possible that there is no entry in the database). And for some entries I run into the except block although there is an entry in the database for sure! When using objects.filter() instead of objects.get() I do not have this problem - it never goes to the except block for the same entries in the database!

key = "anystringasprimarykey"
username = "anyusername"
try:
    entry = MyDatabase.objects.get(ort=key, user=username)
except:
    print("oh, exception!")

Can anybody give me a tip on what I am doing wrong?

Epicenter answered 16/2, 2016 at 15:16 Comment(0)
M
3

You run into the error because you find more than one instance of an object, if that is a possibility then you should be using filter(), get() is more for cases where you're sure theres only one possible entry.

What is currently happening is you're catching all errors, not just the DoesNotExist error which you may be used to..

From the docs, you can see that get is capable of capturing two different errors - MultipleObjectsReturned and DoesNotExist, you are getting the former. If you wish to continue using get you should catch both explicitly

try:
    entry = MyDatabase.objects.get(ort=key, user=username)
except MultipleObjectsReturned:
    print("oh, I've forgotten to do something with the exception!")
except DoesNotExist:
    print("oh, I've forgotten to do something with the exception!")

In terms of your actual error handling, just printing to the console isn't very helpful, it probably means that code following this isn't able to function correctly without the missing entry value, you may want to either return an error response (I.e HttpResponseNotFound), log the error, or provide a default value to continue along with.

Madsen answered 16/2, 2016 at 15:17 Comment(3)
Besides that, you should use except MyDatabase.DoesNotExist to capture more exact type of exception. It is the general except that hides the exception you are confused of.Carnelian
@ShangWang - That is true, I've added an addendum to my question for that (which I'm extending upon)Madsen
I Thank You very much, that was my problem!Epicenter
C
5

objects.get() is used when you are pretty sure that there is only one result. But its better to use objects.filter().first(), because it won't cause any errors. For example you could write:

entry = MyDatabase.objects.filter(ort=key, user=username).first()

instead of

entry = MyDatabase.objects.get(ort=key, user=username)

Then you can check whether the query returned any object:

if entry:
    #some actions
Chordate answered 16/2, 2016 at 17:52 Comment(0)
M
3

You run into the error because you find more than one instance of an object, if that is a possibility then you should be using filter(), get() is more for cases where you're sure theres only one possible entry.

What is currently happening is you're catching all errors, not just the DoesNotExist error which you may be used to..

From the docs, you can see that get is capable of capturing two different errors - MultipleObjectsReturned and DoesNotExist, you are getting the former. If you wish to continue using get you should catch both explicitly

try:
    entry = MyDatabase.objects.get(ort=key, user=username)
except MultipleObjectsReturned:
    print("oh, I've forgotten to do something with the exception!")
except DoesNotExist:
    print("oh, I've forgotten to do something with the exception!")

In terms of your actual error handling, just printing to the console isn't very helpful, it probably means that code following this isn't able to function correctly without the missing entry value, you may want to either return an error response (I.e HttpResponseNotFound), log the error, or provide a default value to continue along with.

Madsen answered 16/2, 2016 at 15:17 Comment(3)
Besides that, you should use except MyDatabase.DoesNotExist to capture more exact type of exception. It is the general except that hides the exception you are confused of.Carnelian
@ShangWang - That is true, I've added an addendum to my question for that (which I'm extending upon)Madsen
I Thank You very much, that was my problem!Epicenter
U
2

model.objects.get() is not good, never use it. Instead, use filter().first() or filter() alone. Get will throw exception when there is no matching or multiple matchings, it only return single object. Filter on the other side, will return a queryset not matter what, which is much more better, caz it can return queryset with zero element or multiple elements or single element.

Urinal answered 25/12, 2021 at 7:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.