2016-09-21 3 views
0

Я использую django 1.10.1, postgres 9.5 и redis. У меня есть таблица, которые хранят пользователь голоса, и выглядят как:Попытка минимизировать количество поездок в таблицу голосования базы данных

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

где object и user внешние ключи к id колонку своих собственных таблиц, соответственно.

Проблема в том, что во многих ситуациях мне приходится перечислять многие объекты на одной странице. Если пользователь вошел в систему или прошел проверку подлинности, я должен проверять каждый объект независимо от того, был ли он проголосован или нет (и действовать в зависимости от результата, что-то вроде шоу vote или unvote). Поэтому в моем шаблоне я должен вызвать такую ​​функцию для каждого объекта на странице.

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

Поскольку я, возможно, десятки объектов на одной странице, я нашел, используя django-debug-toolbar, что доступ к базе данных в одиночку может занять более одной секунды, потому что доступ только к одной строке для каждого запроса, и что происходит в сериале путь для всех объектов на странице. Чтобы усугубить ситуацию, я использую подобные запросы из этих таблиц на других страницах (т. Е. Фильтр только с использованием user или только object).

То, что я пытаюсь достичь, и что я думаю, что это правильно, - это найти способ доступа к базе данных только один раз, чтобы получить все объекты, отфильтрованные каким-либо пользователем (может быть, когда пользователь входит в систему или при первом нажатии на страницу, требующем такого доступа к базе данных), а затем отфильтровывать его до того, что я хочу, в зависимости от потребностей страницы. Поскольку я использую redis и приложение django-cacheops, может ли он помочь мне выполнить эту работу?

+0

Как вы получили свои объекты-объекты, пожалуйста, обновите эту часть кода. Где нарисованы redis и django-cache? – e4c5

ответ

0

В вашем случае я бы лучше идти с получением массива идентификаторов объектов и запросов всех голосов по идентификатору пользователя и этот массив, что-то вроде:

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 

Это сделает только один дополнительный запрос к базе данных для получения голосов от пользователя на страницу.

+1

Должен использовать 'queryset.values_list ('pk', flat = True)' для эффективного извлечения pks. – Suor