views:

437

answers:

4

Surely there is a better way to do this?

results = []
if not queryset is None:
    for obj in queryset:
        results.append((getattr(obj,field.attname),obj.pk))

The problem is that sometimes queryset is None which causes an exception when I try to iterate over it. In this case, I just want result to be set to an empty list. This code is from a Django view, but I don't think that matters--this seems like a more general Python question.

EDIT: I turns out that it was my code that was turning an empty queryset into a "None" instead of returning an empty list. Being able to assume that queryset is always iteratable simplifies the code by allowing the "if" statement to be removed. The answers below maybe useful to others who have the same problem, but cannot modify their code to guarantee that queryset is not "None".

+1  A: 

you can use list comprehensions, but other than that I don't see what you can improve

result = []
 if queryset:
     result = [(getattr(obj, field.attname), obj.pk) for obj in queryset]
SilentGhost
One notice: `if queryset` evaluates queryset and retrieve all underlying data
Alex Koshelev
i'm sorry, but i don't see how my snippet is any different in this respect from the original code
SilentGhost
Daevaorn: it doesn't retrieve all underlying data, in boolean context it's smart enough to just do a COUNT().
Carl Meyer
SilentGhost: your version is less efficient. "queryset is None" just does a Python object identity comparison, whereas "if queryset" evaluates queryset in a boolean context, which forces a SQL COUNT() query (since a queryset that returns no rows also evaluates to False).
Carl Meyer
+19  A: 
results = [(getattr(obj, field.attname), obj.pk) for obj in queryset or []]
J.F. Sebastian
I don't recall the operator priority exactly, but you might have to put:for obj in (queryset or [])
Gabriel Ross
@Gabriel: parentheses are unnecessary. Though you might add them for readability if you rarely see such code.
J.F. Sebastian
Wow, that's superb!
artknish
+8  A: 

How about

for obj in (queryset or []):
    # Do your stuff

It is the same as J.F Sebastians suggestion, only not implemented as a list comprehension.

kigurai
+2  A: 

For what it's worth, Django managers have a "none" queryset that you can use to avoid gratuitous None-checking. Using it to ensure you don't have a null queryset may simplify your code.

if queryset is None:
    queryset = MyModel.objects.none()

References:

Joe Holloway