xpeterpanx009
xpeterpanx009

Reputation: 21

django, check if object is part of queryset not returning proper value

for some reason I keep getting 'False' output and iim not sure why.. this is my queryset and condition in my view

def book(request):
    test = books.objects.all().values('user')
    print(test)
    print(request.user.id)
    if request.user.id in test:
        exist = True
    else:
        exist = False

    print(exist)

this is the console output, im expecting True, but im not sure why it isn't searching through it correctly. is it cause it's a list of tuples?

<QuerySet [{'user': 1}, {'user': 1}, {'user': 1}, {'user': 1}, {'user': 1}, {'user': 3}]>                                                   
currently logged in user id:  1                                                                                                             
False  

Upvotes: 1

Views: 1008

Answers (3)

bruno desthuilliers
bruno desthuilliers

Reputation: 77942

You already have the proper solution for your current use case, but your question is left unanswered so:

im not sure why it isn't searching through it correctly. is it cause it's a list of tuples?

Actually, those are not tuples but dicts (and to be anal, it's not a list but a queryset - but this is irrevelant here xD)

Now forget about Django assume we indeed have a plain list of dicts:

test = [
  {'user': 1}, {'user': 1}, {'user': 1}, 
  {'user': 1}, {'user': 1}, {'user': 3}
  ]

and a user_id integer:

user_id = 1

then expression

user_id in test

actually amounts to:

found = False
for item in test:
    if item == user_id:
        found = True
        break

Now since items in test are dicts, you are actually testing:

{'user': 1} == 1

which is garanteed to ever be false, since a dict and an int can obviously not compare equal ;-)

What you would need here (in pure Python I mean - hopefully a SQL db can do better) would be either comparing user_id with each item's 'user' value:

found = False
for item in test:
    if item["user"] == user_id:
        found = True
        break

or build a similar dict so you directlty use containment test:

target = {"user": user_id}
target in test

Upvotes: 0

xpeterpanx009
xpeterpanx009

Reputation: 21

test = books.objects.filter(user_id = request.user.id).exists()
print(test)

this worked as intended. I can now return the value :)

Upvotes: 0

JPG
JPG

Reputation: 88669

You can use exists(...) method as,

def book(request):
    exist = books.objects.filter(user=request.user).exists()
    print(exist)

Upvotes: 3

Related Questions