django-autocomplete-light: Как кэшировать варианты?

У меня есть собственная модель города (не django-cities-light) с более чем 2M записями в таблице MySQL. Каждый раз, когда я начинаю вводить поле автозаполнения, загрузка процессора в таблице htop в процессе mysqld превышает 200%, поэтому похоже, что скрипт запрашивает таблицу при каждом автозаполнении.

Я хотел бы поместить таблицу в memcache, чтобы избежать этого, и вот что у меня есть:

autocomplete_light_registry.py

import autocomplete_light
from django.core.cache import cache, InvalidCacheBackendError
from cities.models import City

def prepare_choices(model):
    key = "%s_autocomplete" % model.__name__.lower()
    try:
        qs = cache.get(key)
        if cache.get(key): # return if not expired
            return qs
    except InvalidCacheBackendError:
        pass
    qs = model.objects.all()     # populate cache
    cache.set(key, qs, 60*60*24) # if expired or not set
    return qs

class CityAutocomplete(autocomplete_light.AutocompleteModelBase):
    search_fields = ['city_name']
    choices = prepare_choices(City)
autocomplete_light.register(City, CityAutocomplete)

Но он все еще продолжает запрашивать mysql.

Какие-либо предложения?

ОБНОВИТЬ

Я попытался установить кеш для таблицы городов в оболочке django, но процесс прерывается сообщением Ошибка сегментации.

>>> from django.core.cache import cache
>>> qs = City.objects.all()
>>> qs.count()
2246813
>>> key = 'city_autocomplete'
>>> cache.set(key, qs, 60*60*24)
Segmentation fault

Но мне удалось поместить в кеш меньшие таблицы, и я надеюсь решить эту проблему, поэтому ответ все еще нужен.


person Vlad T.    schedule 11.05.2014    source источник
comment
Не могли бы вы опубликовать список запросов SQL, сделанных одним запросом автозаполнения? Спасибо !   -  person jpic    schedule 16.06.2014


Ответы (1)


cache.set(key, qs, 60*60*24) Ошибка сегментации

это произошло потому, что запрос слишком большой. Вам нужно будет кэшировать это ПОСЛЕ его фильтрации.

вот как я это сделал. Не идеально, но хорошо работало с 500 элементами.

def get_autocomplete(request):
    if request.is_ajax():
        q = request.GET.get('term', '')
        results_list = MY_model.objects.filter(title__contains=q).all()
        results = []
        for result in results_list:
            results.append(result)
        data = json.dumps(results)
    else:
        data = 'Nothing to see here!'
    mimetype = 'application/json'
    return http.HttpResponse(data, mimetype)

Нашел это где-то в сети.

Вам понадобятся в лучшем случае первые 10 элементов, так как остальные исчезнут с экрана.

person Deil    schedule 17.11.2016