RompePC
RompePC

Reputation: 835

Django manager first() vs Model.objects.all()[:1]

I would like to know if first() is the same as limiting querysets.

Is Model.objects.first() the same as Model.objects.all()[:1] in speed?

You've to remember that first() is the same as Model.objects.all()[0], so my thoughts are that they aren't the same, but then I don't understand why we have a handy method as first().

Upvotes: 10

Views: 11732

Answers (2)

chachan
chachan

Reputation: 2452

Regarding speed. Using timeit module in ipython I found:

In [11]: %timeit rompepc.models.SampleModel.objects.all()[:1][0]                  
1000 loops, best of 3: 326 µs per loop                                       

In [12]: %timeit rompepc.models.SampleModel.objects.first()                    
1000 loops, best of 3: 464 µs per loop

There is still a difference when you try to access to fields

In [14]: %timeit rompepc.models.SampleModel.objects.all()[:1][0].sample_field  
1000 loops, best of 3: 323 µs per loop                                         

In [15]: %timeit rompepc.models.SampleModel.objects.first().sample_field       
1000 loops, best of 3: 461 µs per loop

Have in mind that you would need to validate length before using the indexed version. Answering your question, it seems like is not the same.

Note: There're only two records in the model with a single char field. Database is SQLite3. It may behaves different with more records, fields and another DB engine

Upvotes: 6

Udi
Udi

Reputation: 30522

Model.objects.first() returns one instance or None, while Model.objects.all()[:1] returns a slice of the queryset, with zero or one instances. Here is first()'s source code from Django 1.10:

def first(self):
    """
    Returns the first object of a query, returns None if no match is found.
    """
    objects = list((self if self.ordered else self.order_by('pk'))[:1])
    if objects:
        return objects[0]
    return None

Upvotes: 9

Related Questions