[Django]-Difference between values() and only()

38👍

Assuming Blabla has the fields in your question, as well as field4,

Blabla.objects.only('field1', 'field2', 'field3')[0].field4

will return the value of that object’s field4 (with a new database query to retrieve that info), whereas

Blabla.objects.values('field1', 'field2', 'field3')[0].field4

will give

AttributeError: 'dict' object has no attribute 'field4'

This is because .values() returns a QuerySet that returns dictionaries, which is essentially a list of dicts, rather than model instances (Blabla).

24👍

The answers given so far are correct, but they don’t mention some of the differences in terms of queries. I will just report them.

.get()

# User.objects.get(email='user@email.com').username

SELECT "users_user"."id", "users_user"."password", "users_user"."last_login", 
"users_user"."is_superuser", "users_user"."username", "users_user"."first_name", 
"users_user"."last_name", "users_user"."email", "users_user"."is_staff", "users_user"."is_active", 
"users_user"."date_joined", "users_user"."name"
FROM "users_user" 
WHERE "users_user"."email" = 'user@email.com'; args=('user@email.com',)

.only().get()

# User.objects.only('username').get(email='user@email.com')

SELECT "users_user"."id", "users_user"."username" 
FROM "users_user" 
WHERE "users_user"."email" = 'user@email.com'; args=('user@email.com',)

.values().get()

# User.objects.values('username').get(email='user@email.com')

SELECT "users_user"."username" 
FROM "users_user" 
WHERE "users_user"."email" = 'user@email.com'; args=('user@email.com',)

As you can see, only() will also select the id of the record. This is probably because of the fact that it will output a model that you can later use, as the other answers mentioned.

19👍

.values() gives you "less than a model"; the items it returns are closer to dictionaries than full models, which means you don’t get the model attributes but you also don’t have to initialize full models.

.only() restricts the field list in the SQL to specific fields you care about, but still initializes a full model; it defers loading of the other fields until you access them (if at all).

3👍

values() returns QuerySet – which when iterated returns dictionaries representing the model. It does not return model objects.

only() is a way of restricting the columns returned, and ensuring that only those columns are returned immediately – which is why it is sometimes referred to as the opposite of defer() It is the equivalent of saying SELECT foo, bar, zoo FROM rather than the normal SELECT [all columns] FROM. It will return a QuerySet that can further be chained.

Leave a comment