0

I use django 1.10.1, postgres 9.5 and redis. I have a table that store users votes and looks like:

==========================
object | user | created_on
==========================

where object and user are foreign keys to the id column of their own tables respectively.

The problem is that in many situations, I have to list many objects in one page. If the user is logged in or authenticated, I have to check for every object whether it was voted or not (and act depending on the result, something like show vote or unvote button). So in my template I have to call such function for every object in the page.

def is_obj_voted(obj_id, usr_id):
    return ObjVotes.objects.filter(object_id=obj_id, user_id=usr_id).exists()

Since I may have tens of objects in one page, I found, using django-debug-toolbar, that the database access alone could take more than one second because I access just one row for each query and that happens in a serial way for all objects in the page. To make it worse, I use similar queries from that tables in other pages (i.e. filter using user only or object only).

What I try to achieve and what I think it is the right thing to do is to find a way to access the database just once to fetch all objects voted filtered by some user (maybe when the user logs in in or the at the first page hit requiring such database access), and then filter it further to whatever I want depending on the page needs. Since I use redis and django-cacheops app, can it help me to do that job?

Ejonas GGgg
  • 446
  • 1
  • 6
  • 19
  • how did you get your object_ids please update with that part of the code. Where does redis and django-cache come into the picture? – e4c5 Sep 22 '16 at 00:28

1 Answers1

0

In your case I'd better go with getting an array of object IDs and querying all votes by user's ID and this array, something like:

object_ids = [o.id for o in Object.objects.filter(YOUR CONDITIONS)]
votes = set([v.object_id for v in ObjVotes.objects.filter(object_id__in=object_ids, user_id=usr_id)]
def is_obj_voted(obj_id, votes):
    return obj_id in votes

This will make only one additional database query for getting votes by user per page.

icuken
  • 1,306
  • 9
  • 11