前台页面快速响应

一、问题引入

  一般前台会有很多过滤选项,然后根据过滤选项去后台数据库中取出数据,但有时取出数据会经过一些业务逻辑处理,导致响应速度较慢,此时可以这样考虑,可以将所有的过滤选项进行组合,然后后台将这些组合通过定时任务事先跑一边,然后将结果存储在redis或者其它内存数据库中。

  这样,前台每次过滤选项的值优先从redis中取出,这样会大大加快响应速度。

  不过这种方式适用于过滤条件比较少的情况,而且是比较过滤的过滤选项,如果过滤选项中有时间过滤,这就不太合适了。

二、实例

前台过滤条件一般可通过select这样的表单组件来实现,假如现在提交到后台的选项包含以下的可能:

"""
[
{'course':1},
{'course':2}
]

[
{'teacher':1},
{'teacher':2}
]
"""

现在需要将上述过滤条件的所有可能进行组合,然后通过定时任务计算出所有的可能组合的值,并且将其存入到内存中:

from functools import reduce

list1 = [
{'course':1},
{'course':2}
]

list2 =[
{'teacher':1},
{'teacher':2}
]

def list_con(lists,code=''):
    """进行组合"""
    def my_func(list1,list2):
        return [str(i)+code+str(j) for i in list1 for j in list2]
    return reduce(my_func,lists)

l = list_con([list1,list2])
"""
[
"{'course': 1}、{'teacher': 1}",
 "{'course': 1}、{'teacher': 2}",
  "{'course': 2}、{'teacher': 1}", 
  "{'course': 2}、{'teacher': 2}"
  ]
"""
def str_to_dict():
    """"将字典进行分割"""
    obj_dict_list = list()
    for i in l:
        sp = i.split("")
        obj_dict_list.append(sp)
    return obj_dict_list

l1 = str_to_dict()
"""
[
["{'course': 1}", "{'teacher': 1}"],
 ["{'course': 1}", "{'teacher': 2}"], 
 ["{'course': 2}", "{'teacher': 1}"], 
 ["{'course': 2}", "{'teacher': 2}"]
 ]
"""

def eval_dict():
    """将上述字符串转成字典形式"""
    filter_list = []
    for j in l1:
        obj_list = list()
        for k in j:
            obj_list.append(eval(k))
        filter_list.append(obj_list)
    return filter_list
l2 = eval_dict()
"""
[
[{'course': 1}, {'teacher': 1}], [{'course': 1}, {'teacher': 2}],
 [{'course': 2}, {'teacher': 1}], [{'course': 2}, {'teacher': 2}]
 ]

"""

def dict_con(multi_dict):
    """将字典进行组合"""
    def my_func(dict1,dict2):
        return dict(dict1,**dict2)
    return reduce(my_func,multi_dict)

fi_list = []
for m in l2:
    res = dict_con(m)
    fi_list.append(res)
print(fi_list) #
"""
[
{'course': 1, 'teacher': 1}, 
{'course': 1, 'teacher': 2}, 
{'course': 2, 'teacher': 1}, 
{'course': 2, 'teacher': 2}
]
这些组合可以直接通过数据库查询,比如django orm的filter传入上述的字典形式即可
"""


from uuid import uuid4

def gen_key():
    """生成redis的key,过滤条件字符不规范,可以使用uuid生成唯一的key"""
    key_dict = {}
    for item in fi_list:
        key_dict[str(item)] = uuid4()
    return key_dict
print('gen',gen_key())
"""
{
"{'course': 2, 'teacher': 2}": UUID('a8a505ad-96fc-4236-81f9-29d81cce4c91'), 
"{'course': 1, 'teacher': 2}": UUID('73ebacb3-dcd4-46dc-bf2d-f49206201c90'), 
"{'course': 2, 'teacher': 1}": UUID('5c2614c2-a316-4220-a7a9-6c8c63515003'), 
"{'course': 1, 'teacher': 1}": UUID('99d760c4-5238-4283-bfab-dfdc2dffbc72')
}
比如将{'course': 2, 'teacher': 2}过滤条件下的值计算出来,然后通过set(key,value),其中key就是对应的uuid值
设置到redis中
"""

当前台页面传入过滤条件后先与所有的可能组合(事先以文件或者其它形式将所有可能存储起来)进行比对,然后选择对应的uuid,然后去内存中取值即可。

原文地址:https://www.cnblogs.com/shenjianping/p/13416966.html