Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems when using dict comprehensions. NameError: global name is not defined

I am trying to create a dict with key as name and value as corresponding User object.

I am using Python shell from Django shell wrapper python manage.py shell:

>>> from django.contrib.auth.models import User
>>> names = ['carl', 'jim', 'jack', 'john', 'mark']
# Now using some dict comprehension
>>> u = {name: User.objects.get(username=name) for name in names}
NameError: global name 'User' is not defined

However, this works for me:

u = {}
for name in names:
    u[name] = User.objects.get(username=name)

And I get the desired output, which is:

{ 
  'carl': <User: carl>,
  'jack': <User: jack>,
  'jim' : <User: jim>,
  'john': <User: john>,
  'mark': <User: mark>
}

I know, there are other ways to accomplish this, but I am curious why are the dict comprehensions not working here.

Any tips?
Am I missing something here?

like image 362
Dhruv Baldawa Avatar asked Oct 30 '12 08:10

Dhruv Baldawa


1 Answers

I believe python's issue tracer is the best answer for you.

In short: it won't work in shell. The same applies to function definition in shell. The imports are unaccesible there.

In regard for your problem I advise:

names = [...]
users = User.objects.filter(username__in=names)
name_to_user = {user.username: user for user in users}

It does one sql query instead of len(names).

like image 78
Krzysztof Szularz Avatar answered Oct 24 '22 04:10

Krzysztof Szularz