Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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().

like image 840
RompePC Avatar asked Mar 06 '17 09:03

RompePC


People also ask

What does First () do in Django?

first() : It will return the first item of a recordset. If no record exists, it returns None .

How do you get or view all the items in a model in Django?

The simplest way you can get the list of objects of an attribute is to first get a query-set of that attribute alone using values_list then converting the django query-set to a python set using set() and finally to a list using list() .

What does model manager do in Django?

A Manager is the interface through which database query operations are provided to Django models. At least one Manager exists for every model in a Django application. The way Manager classes work is documented in Making queries; this document specifically touches on model options that customize Manager behavior.

What does Django DB models model clean () do?

clean() This method should be used to provide custom model validation and to modify attributes on your model if desired.


2 Answers

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
like image 198
Udi Avatar answered Sep 17 '22 06:09

Udi


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

like image 26
chachan Avatar answered Sep 18 '22 06:09

chachan