Reputation: 765
I have a Document model which has a many to many "favorites" relationship to User. When I display a list of Documents on the search page I would like to show whether each document is a favorite or not for the current user. I know two ways of doing this, one more efficient and one cleaner. I am wondering if there is another way I can do it so that it's both efficient and clean.
Clean version. Simply have a method on the model "is_favored(user)" that tells whether the document is favored by the given user. Then have a simple template tag that uses this function to display an empty star or a filled star. Of course this is not efficient since it would make a different DB call for each document. But it's nice because the view does not have to be changed in any way.
Efficient version. Do a single database query in the view to retrieve the favorite queries and add a "favored" field on each Document. I don't like this approach because I will have to add custom code to all views that display Documents and it's not too DRY.
Is there a better approach that is both DRY and efficient? Thanks.
Upvotes: 1
Views: 78
Reputation: 1213
Context processors are what you are looking for.
Here you can read about it: http://www.djangobook.com/en/2.0/chapter09.html (check out RequestContext and Context Processors section)
edit:
You can also simply create a function that takes user and list of documents currently displayed in search results. Something like this:
def favs(user, docs):
l = user.favorites.filter(pk__in=docs).values_list('pk', flat=True)
return dict( (k, (k in l)) for k in docs )
So now, we have dictionary that says if document with given id is favorite or not. And then call that function in each view and use its results.
It is DRY now (cause if you want to change f.e. name of attribute "favorites" you have to do only one change.
Upvotes: 1