But a get is more efficient than a filter.
This is simply not true. A .get(…) will generate exactly the same SQL as a .filter(…).
Using:
SomeModel.objects.filter(pk=1)[0:1].values_list('title', flat=True)
Will do what you want, and will have exactly the same performance characteristics as .get(…) (actually, it will be a bit faster, because .get(…) checks to see if more than one row would be returned…):
In [4]: import logging
In [5]: l = logging.getLogger("django.db")
In [6]: l.setLevel(logging.DEBUG)
In [7]: User.objects.filter(id=1)[0:1].values_list()
DEBUG:django.db.backends:(0.006) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1 LIMIT 1; args=(1,)
Out[7]: [(1, u'admin', u'Admin', u'User', u'[email protected]', u'sha1$bf3bc$daa1fb58a8a41e15c730ae86bc0faf4c01fdd3a1', True, True, True, datetime.datetime(2013, 1, 8, 21, 15, 51, 855527), datetime.datetime(2012, 1, 10, 15, 13, 55))]
In [8]: User.objects.get(id=1)
DEBUG:django.db.backends:(0.001) SELECT "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."id" = 1 ; args=(1,)
Out[8]: <User: admin>
filterandget. What really matters is that you don't perform 1+N queries. Your current code almost looks like you are executing this query for various keys. If this is the case you should either perform a join or usepk__in=[1,2,3,4,5]to fetch the titles of more than one object at the same time.filterandgetbecause there isn't any ;)getwill be faster because it will throw an exception right away!