On 10 November 2010 22:10, Shawn Milochik <sh...@milochik.com> wrote: > 2010/11/10 Łukasz Rekucki <lreku...@gmail.com>: >> On 10 November 2010 21:55, Shawn Milochik <sh...@milochik.com> wrote: >>> The queryset returns zero or more instances of your model. So if >>> there's only one result, you can just get the first item in the >>> queryset by its index. >>> >>> For example: >>> >>> some_queryset = YourModel.objects.filter(**kwargs) >>> >>> if some_queryset.count() == 1: >>> x = some_queryset[0] >>> #x is now an instance of your model. >>> else: >>> raise ValueError("%d results -- expected one!" % (some_queryset.count(),) >> >> This is a very bad way of checking queryset length, because count() >> actually creates a new QuerySet that gets executed (again!). Instead >> use len() that will first check against queryset's internal cache. > > I agree that your way is better, but I disagree about duplicate > execution -- doing a count() will simply run a SQL query that does a > COUNT. It's not doing anything "again" because the original queryset > hasn't actually been executed (lazy) until its contents are actually > used (as in the variable assignment), and the COUNT statement is > lightweight.
Yes, the original query is lazy. But the common case here is probably that element exists, so most of the time you will be doing: some_queryset.count() # ~= SELECT COUNT(*) FROM ... some_queryset[0] # ~= SELECT mymodel.* FROM ... LIMIT 1 How those queries are performed of course depends on the params you pass to filter(), but the COUNT() is not as light-weight as you think. Assuming the simplest case of filtering by primary key, It's actually pretty slow and requires to go through the whole index (or even a full table scan), while a LIMIT 1 query usualy just fetches the first element in the db index. This is why Django 1.2 has .exists() which uses LIMIT 1. -- Łukasz Rekucki -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-us...@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.