Skip to main content
 首页 » 编程设计

python之django-autocomplete-light:如何缓存选择

2025年05月04日36xiaohuochai

我有自己的城市模型(不是 django-cities-light),在 MySQL 表中有超过 2M 的记录。每次我开始在自动完成字段中键入内容时,htop 表上的 CPU 负载在 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 shell 中为 cities 表设置缓存,但该过程因Segmentation fault 消息而中断。

>>> 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 

但是我能够将较小的表放入缓存中,我希望能够克服这个问题,所以仍然需要答案。

请您参考如下方法:

cache.set(key, qs, 60*60*24) Segmentation fault

发生这种情况是因为查询太大了。 您需要在过滤后对其进行缓存。

我就是这样做的。不完美,但确实可以很好地处理 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 个元素,因为其余元素会从屏幕中弹出。