views:

85

answers:

2

Say I have a model object 'Person' defined, which has a field called 'Name'. And I have a list of people:

l = ['Bob','Dave','Jane']

I would like to return a list of all Person records where the first name is not in the list of names defined in l.

What is the most pythonic way of doing this?

EDIT: After thinking about it, what I really was trying to do is come up with a sub list of l that wasn't present in the Person table. Is there an efficient way of doing this? I can think of a few ways, not sure how efficient though.

+1  A: 

This should work:

Person.objects.exclude(name__in=['Bob','Dave','Jane'])

Michael
+2  A: 

Renaming l for readability:

names = ['Bob','Dave','Jane']

Person.objects.[exclude][1](Name__[in][2]=names)

UPDATE 1: Answer to the second question (in your 'EDIT' paragraph):

present = Person.objects.values_list('Name', flat=True)
absent = set(names) - set(present)   
# or, if you prefer named functions to the set operator '-'
absent = set(names).difference(present) 

Yes, the "right hand side" of difference (but not '-') accepts any iterable (I had to look it up to confirm).

msw
This is the right approach, but use `Person.objects.values_list('Name', flat=True')` instead of your list comprehension to get the list of names.
Daniel Roseman
@daniel: thanks, django newbie here
msw
@daniel, not sure i understand. Can you rewrite msw's example line?
Rhubarb
@Rhubarb: I edited the UPDATE 1 code block for you.
msw
@msw, actually you didn't need the list comprehension at all with the `flat=True`. Hope you don't mind, I've edited it myself.
Daniel Roseman
@daniel no worries about the edit but I was getting a list of 1-tuples out. Time to figure what I botched, thanks again.
msw