2024-12-03 01:29:28
导读:很多朋友问到关于django中filter中怎么使用或者的相关问题,本文首席CTO笔记就来为大家做个详细解答,供大家参考,希望对大家有所帮助!一起来看看吧!
Django的orm中get和filter的不同首先对比下两个函数文档上的解释。
get
Returnstheobjectmatchingthegivenlookupparameters,whichshouldbeintheformatdescribedinFieldlookups.
get()raisesMultipleObjectsReturnedifmorethanoneobjectwasfound.TheMultipleObjectsReturnedexceptionisanattributeofthemodelclass.
get()raisesaDoesNotExistexceptionifanobjectwasn’tfoundforthegivenparameters.Thisexceptionisalsoanattributeofthemodelclass
filter
ReturnsanewQuerySetcontainingobjectsthatdonotmatchthegivenlookupparameters.
Thelookupparameters(**kwargs)shouldbeintheformatdescribedinFieldlookupsbelow.MultipleparametersarejoinedviaANDintheunderlyingSQLstatement,andthewholethingisenclosedinaNOT().
输入参数
get的参数只能是model中定义的那些字段,只支持严格匹配
filter的参数可以是字段,也可以是扩展的where查询关键字,如in,like等
返回值
get返回值是一个定义的model对象
filter返回值是一个新的QuerySet对象,然后可以对QuerySet在进行查询返回新的QuerySet对象,支持链式操作
QuerySet一个集合对象,可使用迭代或者遍历,切片等,但是不等于list类型(使用一定要注意)
异常
get只有一条记录返回的时候才正常,也就说明get的查询字段必须是主键或者唯一约束的字段。当返回多条记录或者是没有找到记录的时候都会抛出异常
filter有没有匹配的记录都可以
pythondjango在前端怎么遍历得到字典的value这是哪儿的django面试题目或者笔试题目吧,请查看django开发手册。
1.queryset是查询集,就是传到服务器上的url里面的查询内容。Django会对查询返回的结果集QuerySet进行缓存,这是为了提高查询效率。也就是说,在你创建一个QuerySet对象的时候,Django并不会立即向数据库发出查询命令,只有在你需要用到这个QuerySet的时候才会这样做。
2.Objects是django实现的mvc中的m,Django中的模型类都有一个objects对象,它是一个Django中定义的QuerySet类型的对象,它包含了模型对象的实例。
3.不能,因为get可能会有异常,可以用filter函数,如下
Entry.objects.filter(blog__id__exact=1)#显示的使用__exact
Entry.objects.filter(blog__id=1)#隐含的使用__exactEntry.objects.filter(blog__pk=1)#__pk相当于__id__exact
python中的filter()函数怎么用?特别是一个函数有多个输入参数时。map是把函数调用的结果放在列表里面返回,它也可以接受多个iterable,在第n次调用function时,将使用iterable1[n],iterable2[n],...作为参数。
filter(function,iterable)
这个函数的功能是过滤出iterable中所有以元素自身作为参数调用function时返回True或bool(返回值)为True的元素并以列表返回.
deff_large_than_5(x):
returnx5
filter(f_large_than_5,range(10))
[6,7,8,9]
django先exclude再filterModel.objects.exclude(xxxx=xx).filter(xxxx=xx)
这样就可以了,可以连贯操作的。。。
filter里面也可以多个filter(xxxx=xx,aaa=aa,bbb=bb)
djangomodel的get和filter方法的区别
get只能返回一个model对象,只能是1个,不是1个全报异常,通常用于主键查询比较合适:get(id=1)
filter返回的queryset可以有0个,1个、多个model对象,没有限制。
如何有效的遍历django的QuerySet最近做了一个小的需求,在django模型中通过前台页面的表单的提交
(post),后台对post的参数进行解析,通过models模型查询MySQL,将数据结构进行加工,返回到前台页面进行展示。由于对django中
QuerySet特性的不熟悉,所以测试过程中发现了很多问题。
开始的阶段没有遇到什么问题,我们举例,在models有一张员工表
employee,对应的表结构中,postion列表示员工职位,前台post过来的参数赋给position,加上入职时间、离职时间,查询操作通过
models.filter(position=params)完成,获取的员工信息内容由QuerySet和当前展示页与每页展示的记录数进行简单的计
算,返回给前台页面进行渲染展示。编码如下:
1defget_employees(position,start,end):
2returnemployee.objects.filter(alert_time__lt=end,alert_time__gt=start).filter(position__in=position)
3
4
5@login_required
6defshow(request):
7ifnotvalidate(request):
8returnrender_to_response('none.html',
9context_instance=RequestContext(request,'msg':'paramserror')
10)
11
12position=request.REQUEST.get('position')
13time_range=request.REQUEST.get('time')
14start,end=time_range[0],time_range[1]
15
16num_per_page,page_num=get_num(request)
17all_employees=get_employees(position,start,end)
18#根据当前页与每页展示的记录数,取到正确的记录
19employees=employees_events[(page_num-1)*num_per_page:page_num*num_per_page]
20
21returnrender_to_response('show_employees.html',
22context_instance=RequestContext(
23request,
24'employees':employees,
25'num_per_page':num_per_page,
26'page_num':page_num,
27'page_options':[50,100,200]
28)
29)
运行之后可以正确的对所查询的员工信息进行展示,并且查询速度很快。
employee表中存放着不同职位的员工信息,不同类型的详细内容也不相同,假设employees有一列名为infomation,存储的是员工的详
细信息,infomation={'age':33,'gender':'male','nationality':'German',
'degree':'doctor','motto':'justdo
it'},现在的需求是要展示出分类更细的员工信息,前台页面除了post职位、入职离职时间外,还会对infomation中的内容进行筛选,这里以查
询中国籍的设计师为例,在之前的代码基础上,需要做一些修改。员工信息表employee存放于MySQL中,而MySQL为ORM数据库,它并未提供类
似mongodb一样更为强大的聚合函数,所以这里不能通过objects提供的方法进行filter,一次性将所需的数据获取出来,那么需要对type
进行过滤后的数据,进行二次遍历,通过information来确定当前记录是否需要返回展示,在展示过程中,需要根据num_per_page和
page_num计算出需要展示数据起始以及终止位置。
1defget_employees(position,start,end):
2returnemployee.objects.filter(alert_time__lt=end,alert_time__gt=start).filter(position__in=position)
3
4
5deffilter_with_nation(all_employees,nationality,num_per_page,page_num):
6result=[]
7
8pos=(page_num-1)*num_per_page
9cnt=0
10start=False
11foremployeeinall_employees:
12info=json.loads(employee.information)
13ifinfo.nationality!=nationality:
14continue
15
16#获取的数据可能并不是首页,所以需要先跳过前n-1页
17ifcnt==pos:
18ifstart:
19break
20cnt=0
21pos=num_per_page
22start=True
23
24ifstart:
25result.append(employee)
26
27returnemployee
28
29
30@login_required
31defshow(request):
32ifnotvalidate(request):
33returnrender_to_response('none.html',
34context_instance=RequestContext(request,'msg':'paramserror')
35)
36
37position=request.REQUEST.get('position')
38time_range=request.REQUEST.get('time')
39start,end=time_range[0],time_range[1]
40
41num_per_page,page_num=get_num(request)
42all_employees=get_employees(position,start,end)
43
44nationality=request.REQUEST.get('nationality')
45
46employees=filter_with_nation(all_employees,num_per_page,page_num)
47
48returnrender_to_response('show_employees.html',
49context_instance=RequestContext(
50request,
51'employees':employees,
52'num_per_page':num_per_page,
53'page_num':page_num,
54'page_options':[50,100,200]
55)
56)
当编码完成之后,在数据employee表数据很小的情况下测试并未发现问
题,而当数据量非常大,并且查询的数据很少时,代码运行非常耗时。我们设想,这是一家规模很大的跨国公司,同时人员的流动量也很大,所以employee
表的数据量很庞大,而这里一些来自于小国家的员工并不多,比如需要查询国籍为梵蒂冈的员工时,前台页面进入了无尽的等待状态。同时,监控进程的内存信息,
发现进程的内存一直在增长。毫无疑问,问题出现在filter_with_nation这个函数中,这里逐条遍历了employee中的数据,并且对每条
数据进行了解析,这并不是高效的做法。
在网上查阅了相关资料,了解到:
1Django的queryset是惰性的,使用filter语句进行查询,实际上并没有运行任何的要真正从数据库获得数据
2只要你查询的时候才真正的操作数据库。会导致执行查询的操作有:对QuerySet进行遍历queryset,切片,序列化,对QuerySet应用list()、len()方法,还有if语句
3当第一次进入循环并且对QuerySet进行遍历时,Django从数据库中获取数据,在它返回任何可遍历的数据之前,会在内存中为每一条数据创建实例,而这有可能会导致内存溢出。
上面的原来很好的解释了代码所造成的现象。那么如何进行优化是个问题,网上有
说到当QuerySet非常巨大时,为避免将它们一次装入内存,可以使用迭代器iterator()来处理,但对上面的代码进行修改,遍历时使用
employee.iterator(),而结果和之前一样,内存持续增长,前台页面等待,对此的解释是:usingiterator()
willsaveyousomememorybynotstoringtheresultofthecache
internally(thoughnotnecessarilyonPostgreSQL!);butwillstill
retrievethewholeobjectsfromthedatabase。
这里我们知道不能一次性对QuerySet中所有的记录进行遍历,那么只能对
QuerySet进行切片,每次取一个chunk_size的大小,遍历这部分数据,然后进行累加,当达到需要的数目时,返回满足的对象列表,这里修改下
filter_with_nation函数:
1deffilter_with_nation(all_employees,nationality,num_per_page,page_num):
2result=[]
3
4pos=(page_num-1)*num_per_page
5cnt=0
6start_pos=0
7start=False
8whileTrue:
9employees=all_employees[start_pos:start_pos+num_per_page]
10start_pos+=num_per_page
11
12foremployeeinemployees:
13info=json.loads(employee.infomation)
14ifinfo.nationality!=nationality:
15continue
16
17ifcnt==pos:
18ifstart:
19break
20cnt=0
21pos=num_per_page
22start=True
23
24ifstart:
25result.append(opt)
26
27cnt+=1
28
29ifcnt==num_per_pageornotevents:
30break
31
32returnresult
运行上述代码时,查询的速度更快,内存也没有明显的增长,得到效果不错的优
化。这篇文章初衷在于记录自己对django中queryset的理解和使用,而对于文中的例子,其实正常业务中,如果需要记录员工详细的信息,最好对
employee表进行扩充,或者建立一个字表,存放详细信息,而不是将所有信息存放入一个字段中,避免在查询时的二次解析。
结语:以上就是首席CTO笔记为大家整理的关于django中filter中怎么使用或者的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于django中filter中怎么使用或者的相关内容别忘了在本站进行查找喔。