简介:许多朋友询问了Django是如何解决相关问题的。本文的首席CTO笔记开始为您的参考做出详细的答案。我希望这对每个人都会有所帮助!让我们一起看看!
(帖子),分析背景中帖子的参数,通过模型查询mysql,处理数据结构,然后返回前台页面以示出。
QuerySet功能不熟悉,在测试过程中发现了许多问题。
一开始我没有遇到任何问题。让我们举个例子。模型中有一只员工手表
员工,在相应的表结构中,邮列列代表员工职位,前台帖子的参数被赋予姿势,加上进入时间,出发时间,查询操作通过了通过查询操作的通行
Models.Filter(posity = params)已完成,并且获得的员工信息内容简单地由QuerySet和当前显示页面计算,以及每个页面显示的记录数量。
忘记它,返回首页进行渲染显示。编码如下:
1 def get_employees(位置,开始,结束):
2返回员工。过滤器(posity__in =姿势)
3
4
5 @login_required
6 def show(请求):
7如果没有价值(请求):
8返回render_to_response('none.html',
9 Context_Instance = requestContext(请求,'msg':'params error')
10)
11
12位置= request.request.get('posity')
13 time_range = request.request.get.get('time')
14开始,end = time_range [0],time_range [1]
15
16 num_per_page,page_num = get_num(请求)
17 all_empoloyees = get_employees(姿势,开始,结束)
18#根据当前页面和每个页面显示的记录数量,获取正确的记录
19员工=员工_events [(page_num-1)*num_per_page:page_num*num_per_page]
20
21返回render_to_response('show_employees.html',
22 context_instance = requestContext(
23请求,
24个“员工”:员工,
25'num_per_page':num_per_page,
26'page_num':page_num,
27“ page_options”:[50,100,200]
28)
29)
运行后,您可以正确显示查询的员工信息,并且查询速度很快。
员工表在员工表中有不同的工作信息,并且不同类型的细节不同。假设员工有一个名为Infomation的专栏,该专栏存储更详细的员工的详细员工
详细信息,信息= {'age':33,'gene':'男性','normantity':'dermanity',
'学位':'医生',“座右铭”:'只是做
'}当前的需求是显示更详细的员工信息。除了发布位置和邮政验证时间外,前台还将在信息中筛选内容。
例如,需要根据以前的代码来修改中国国籍的设计师。Employee员工存储在MySQL中,MySQL是一个ORM数据库。它不提供课程
像MongoDB更强大的聚合功能一样,因此您无法使用此处提供的对象制作过滤器的方法,并且您需要一次获取所需的数据。那么您需要输入类型
过滤数据后,执行第二个遍历,并确定当前记录以确定是否需要返回当前记录。在显示过程中,您需要关注num_per_page和
page_num计算出需要显示数据的启动和终止位置。
1 def get_employees(位置,开始,结束):
2返回员工。过滤器(posity__in =姿势)
3
4
5 def filter_wination(all_employees,normantity,num_per_page,page_num):
6结果= []
7
8 pos =(page_num-)*num_per_page
9 CNT = 0
10 start = false
11对于all_employes中的员工:
12 info = json.loads(员工。信息)
13如果info.Nationality!=国籍:
14继续
15
16#获得的数据可能不是主页,因此您需要跳过上一页
17如果cnt == pos:
18如果开始:
19 Bream
20 cnt = 0
21 pos = num_per_page
22开始= true
23
24如果开始:
25结果。申请(员工)
26
27退货员工
28
29
30 @login_required
31 def show(请求):
32如果没有价值(请求):
33返回render_to_response('none.html',,
34 Context_Instance = requestContext(请求,'msg':'params error')
35)
36
37 position = request.request.get.get('posity')
38 time_range = request.request.get.get('time')
39开始,end = time_range [0],time_range [1]
40
41 num_per_page,page_num = get_num(请求)
42 all_employees = get_employees(姿势,开始,结束)
43
44国籍= request.request.get.get('nationality')
45
46名员工= filter_with_nation(all_employees,num_per_page,page_num)
47
48返回render_to_response('show_employees.html',
49 context_instance = requestContext(
50请求,
51“员工”:员工,
52'num_per_page':num_per_page,
53'page_num':page_num,
54'page_options':[50,100,200]
55)
56)
编码完成后,在数据员工表数据很小的情况下找不到测试
问题,当数据量非常大并且查询数据很小时,代码非常耗时。我们想象这是一家大型跨国公司,与此同时,交通量也是很大,所以员工
表格的数据量很大,而且小国的员工不多。例如,当需要查询国籍的员工为梵蒂冈时,前台页面已进入无尽的等待状态。同时,监视过程的内存信息,
该过程的记忆一直在增加。毫无疑问,该问题出现在filter_with_nation函数中,该功能逐一遍历员工中的数据,每件
数据分析不是一种有效的方法。
我在线检查了相关信息,并学到了:
1 django的QuerySet是惰性的。使用过滤器语句进行查询。实际上,它不会运行数据库中的任何数据。
2只要您查询,您就可以真正操作数据库。引起查询的操作是:遍历QuerySet,切片,序列化和list(),QuerySet的Len()方法,以及IF语句
3当第一次输入循环并通过QuerySet时,Django从数据库中获取数据。在返回任何经过的数据之前,它将为内存中的每个数据创建一个实例,这可能会导致内存溢出
以上解释了代码引起的现象。因此如何优化是一个问题,存在在线
当涉及到巨大的QuerySet时,为了避免一次将它们加载到内存中,可以使用迭代器迭代器()处理,但是可以修改上述代码。
雇员.iterator(),结果与以前相同,内存继续增长,前台页面正在等待。这样的解释是:user()
通过不存储缓存的结果,可以为您节省一些内存
Internet(不一定在PostgreSql上进行思考!);但仍然会
从数据库中检索WHO对象。
在这里,我们知道您不能一次穿越QuerySet中的所有记录,因此您只能做
QuerySet切成薄片,采用块尺寸的大小,穿越该部分数据,然后累积。当达到所需数量时,请返回细致对象的列表,然后在此处修改。
filter_with_nation函数:
1 def filter_wination(all_employees,normantity,num_per_page,page_num):
2结果= []
3
4 pos =(page_num-)*num_per_page
5 cnt = 0
6 start_pos = 0
7 start = false
8虽然是真的:
9员工= all_employees [start_pos:start_pos+num_per_page]
10 start_pos += num_per_page
11
30ee的员工12:
13 info = json.loads(员工。infomation)
14如果info.nationality!=国籍:
15继续
16
17如果cnt == pos:
18如果开始:
19 Bream
20 cnt = 0
21 pos = num_per_page
22开始= true
23
24如果开始:
25结果。申请(OPT)
26
27 CNT += 1
28
29如果cnt == num_per_page或不事件:
30休息
31
32返回结果
运行上述代码时,查询速度更快,并且内存不会显着增加。
更改。本文的最初意图是记录我对Django中QuerySet的理解和使用,对于本文中的示例,实际上,在正常业务中,如果您需要记录员工的详细信息,最好是正确
员工表扩展或构建表以存储详细信息,而不是将所有信息放入字段中,以避免查询期间的辅助分析。
具体的写作是
结果= serverInformation.objects.get(id = 1)#filter是querySet,no _meta方法
allhost = serverInformation._meta.get_all_field_names()#this是正确的
vername = serverInformation._meta.get_field('serverType')。Verbose_name#此句子也是正确的,S erverType是模型的属性。
vervalue = serverInformation._meta.get_field('serverzone')。默认#可以获取默认值。如果大家都知道如何获得Verbose_name,为什么不直接想到.default。
PS:
getttr(对象,名称[,默认]))
getttr(x,'foobar')
等同于
X.Foobar
。如果不存在命名的属性,则默认值将拒绝,如果已证明,则会提出属性。
查看如何使用它。
pcr._meta.get_all_field_names()可以获取所有字段的名称,然后您可以使用pcr._meta.get_field()获取Verbose_name,getTattr()以获取值
递归。
使用此函数将递归方法中的所有值提取到空列表
def dict2flatlist(d,l):
打印(D)
对于d.keys()中的x:
如果类型(d [x])== dict:
dict2flatlist(d [x],l)
别的:
L.Append(D [x])
d = {1:“
l = []
dict2flatlist(d,l)
打印(L)
结论:以上是首席CTO的所有内容都指出了Django如何穿越金属群。我希望这对每个人都会有所帮助。如果您仍然想进一步了解这一点,请记住要收集对该网站的关注。