Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get only certain fields of related object in Django

Tags:

python

django

Say I have such models in Django:

class User(models.Model):
    name=models.CharField(...)
    email=models.EmailField(...)
    photo=...
    <other fields>

class Comment(models.Model):
    user=models.ForeignKey(User, ...)

I have a function that receives Comment object and needs just name and email fields to send email (it is just example, obvious)

def sendEmail(comment):
    name, email=comment.user.name, comment.user.email

In implementation presented above, Django will fetch all fields of related object User (something roughly equal to select * from users where id=comment.user_id) Using values_list I can fetch just needed fields:

Users.objects.filter(id=comment.user_id).values_list('name', 'email')

but values_list only applicable to QuerySet object, not to model instance. My question is: is there any way to do the same thing using only "comment" object? It must be equal to select name, email from users where id=comment.user_id by complexity (I don't want to transfer a lot of data stored in some fields over network when I don't need it)

like image 927
fantom Avatar asked Dec 12 '16 17:12

fantom


People also ask

What is __ Str__ in Django?

The __str__ method just tells Django what to print when it needs to print out an instance of the any model. It is also what lets your admin panel, go from this. Note: how objects are just plainly numbered.

What is __ GTE in Django?

Definition and Usage. The gte lookup is used to get records that are larger than, or equal to, a specified value. For a greater than, but not or equal to, search, use the gt lookup.

What does .values do in Django?

values() Returns a QuerySet that returns dictionaries, rather than model instances, when used as an iterable. Each of those dictionaries represents an object, with the keys corresponding to the attribute names of model objects.

How do I get unique items in Django?

If you want to get distinct objects, instead of values, then remove flat=True from the above query, and use values() instead of values_list(). In the above code, we add distinct() at the end of queryset to get distinct values.


1 Answers

If you want to have comments with some additional user data, without having to retrieve whole User objects I believe it's better to fetch additional data when you fetch the comments:

Comment.objects.filter(user=user).values_list('user__name', 'user__email')

Obviously you can fetch other useful Comment fields.

OR:

Comment.objects.filter(user=user).annotate(author_name=F('user__name'),\ 
                                           author_email=F('user__email'))

This still uses the QuerySet API, but both approaches allow you to span relationships to get additional data without extra queries.

like image 173
Ivan Avatar answered Oct 11 '22 07:10

Ivan