首页>>后端>>Python->django中filter中怎么使用或者

django中filter中怎么使用或者

时间:2023-12-07 本站 点击:0

导读:很多朋友问到关于django中filter中怎么使用或者的相关问题,本文首席CTO笔记就来为大家做个详细解答,供大家参考,希望对大家有所帮助!一起来看看吧!

Django的orm中get和filter的不同

首先对比下两个函数文档上的解释。

get

Returns the object matching the given lookup parameters, which should be in the format described in Field lookups.

get() raises MultipleObjectsReturned if more than one object was found. The MultipleObjectsReturned exception is an attribute of the model class.

get() raises a DoesNotExist exception if an object wasn’t found for the given parameters. This exception is also an attribute of the model class

filter

Returns a new QuerySet containing objects that do not match the given lookup parameters.

The lookup parameters (**kwargs) should be in the format described in Field lookups below. Multiple parameters are joined via AND in the underlying SQL statement, and the whole thing is enclosed in a NOT().

输入参数

get 的参数只能是model中定义的那些字段,只支持严格匹配

filter 的参数可以是字段,也可以是扩展的where查询关键字,如in,like等

返回值

get 返回值是一个定义的model对象

filter 返回值是一个新的QuerySet对象,然后可以对QuerySet在进行查询返回新的QuerySet对象,支持链式操作

QuerySet一个集合对象,可使用迭代或者遍历,切片等,但是不等于list类型(使用一定要注意)

异常

get 只有一条记录返回的时候才正常,也就说明get的查询字段必须是主键或者唯一约束的字段。当返回多条记录或者是没有找到记录的时候都会抛出异常

filter 有没有匹配的记录都可以

python django在前端怎么遍历得到字典的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)# 隐含的使用__exact Entry.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的元素并以列表返回.

def f_large_than_5(x):

return x 5

filter(f_large_than_5, range(10))

[6,7,8,9]

django先exclude 再filter

Model.objects.exclude(xxxx=xx).filter(xxxx=xx)

这样就可以了,可以连贯操作的。。。

filter里面也可以多个filter(xxxx=xx,aaa=aa,bbb=bb)

django model的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和当前展示页与每页展示的记录数进行简单的计

算,返回给前台页面进行渲染展示。编码如下:

1 def get_employees(position, start, end):

2 return employee.objects.filter(alert_time__lt=end,alert_time__gt=start).filter(position__in=position)

3

4

5 @login_required

6 def show(request):

7 if not validate(request):

8 return render_to_response('none.html',

9 context_instance=RequestContext(request, 'msg':'params error')

10 )

11

12 position = request.REQUEST.get('position')

13 time_range = request.REQUEST.get('time')

14 start, end = time_range[0], time_range[1]

15

16 num_per_page, page_num = get_num(request)

17 all_employees = get_employees(position, start, end)

18 # 根据当前页与每页展示的记录数,取到正确的记录

19 employees = employees_events[(page_num-1)*num_per_page:page_num*num_per_page]

20

21 return render_to_response('show_employees.html',

22 context_instance=RequestContext(

23 request,

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': 'just do

it'},现在的需求是要展示出分类更细的员工信息,前台页面除了post职位、入职离职时间外,还会对infomation中的内容进行筛选,这里以查

询中国籍的设计师为例,在之前的代码基础上,需要做一些修改。员工信息表employee存放于MySQL中,而MySQL为ORM数据库,它并未提供类

似mongodb一样更为强大的聚合函数,所以这里不能通过objects提供的方法进行filter,一次性将所需的数据获取出来,那么需要对type

进行过滤后的数据,进行二次遍历,通过information来确定当前记录是否需要返回展示,在展示过程中,需要根据num_per_page和

page_num计算出需要展示数据起始以及终止位置。

1 def get_employees(position, start, end):

2 return employee.objects.filter(alert_time__lt=end,alert_time__gt=start).filter(position__in=position)

3

4

5 def filter_with_nation(all_employees, nationality, num_per_page, page_num):

6 result = []

7

8 pos = (page_num-1)*num_per_page

9 cnt = 0

10 start = False

11 for employee in all_employees:

12 info = json.loads(employee.information)

13 if info.nationality != nationality:

14 continue

15

16 # 获取的数据可能并不是首页,所以需要先跳过前n-1页

17 if cnt == pos:

18 if start:

19 break

20 cnt = 0

21 pos = num_per_page

22 start = True

23

24 if start:

25 result.append(employee)

26

27 return employee

28

29

30 @login_required

31 def show(request):

32 if not validate(request):

33 return render_to_response('none.html',

34 context_instance=RequestContext(request, 'msg':'params error')

35 )

36

37 position = request.REQUEST.get('position')

38 time_range = request.REQUEST.get('time')

39 start, end = time_range[0], time_range[1]

40

41 num_per_page, page_num = get_num(request)

42 all_employees = get_employees(position, start, end)

43

44 nationality = request.REQUEST.get('nationality')

45

46 employees = filter_with_nation(all_employees, num_per_page, page_num)

47

48 return render_to_response('show_employees.html',

49 context_instance=RequestContext(

50 request,

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中的数据,并且对每条

数据进行了解析,这并不是高效的做法。

在网上查阅了相关资料,了解到:

1 Django的queryset是惰性的,使用filter语句进行查询,实际上并没有运行任何的要真正从数据库获得数据

2 只要你查询的时候才真正的操作数据库。会导致执行查询的操作有:对QuerySet进行遍历queryset,切片,序列化,对 QuerySet 应用 list()、len()方法,还有if语句

3 当第一次进入循环并且对QuerySet进行遍历时,Django从数据库中获取数据,在它返回任何可遍历的数据之前,会在内存中为每一条数据创建实例,而这有可能会导致内存溢出。

上面的原来很好的解释了代码所造成的现象。那么如何进行优化是个问题,网上有

说到当QuerySet非常巨大时,为避免将它们一次装入内存,可以使用迭代器iterator()来处理,但对上面的代码进行修改,遍历时使用

employee.iterator(),而结果和之前一样,内存持续增长,前台页面等待,对此的解释是:using iterator()

will save you some memory by not storing the result of the cache

internally (though not necessarily on PostgreSQL!); but will still

retrieve the whole objects from the database。

这里我们知道不能一次性对QuerySet中所有的记录进行遍历,那么只能对

QuerySet进行切片,每次取一个chunk_size的大小,遍历这部分数据,然后进行累加,当达到需要的数目时,返回满足的对象列表,这里修改下

filter_with_nation函数:

1 def filter_with_nation(all_employees, nationality, num_per_page, page_num):

2 result = []

3

4 pos = (page_num-1)*num_per_page

5 cnt = 0

6 start_pos = 0

7 start = False

8 while True:

9 employees = all_employees[start_pos:start_pos+num_per_page]

10 start_pos += num_per_page

11

12 for employee in employees:

13 info = json.loads(employee.infomation)

14 if info.nationality != nationality:

15 continue

16

17 if cnt == pos:

18 if start:

19 break

20 cnt = 0

21 pos = num_per_page

22 start = True

23

24 if start:

25 result.append(opt)

26

27 cnt += 1

28

29 if cnt == num_per_page or not events:

30 break

31

32 return result

运行上述代码时,查询的速度更快,内存也没有明显的增长,得到效果不错的优

化。这篇文章初衷在于记录自己对django中queryset的理解和使用,而对于文中的例子,其实正常业务中,如果需要记录员工详细的信息,最好对

employee表进行扩充,或者建立一个字表,存放详细信息,而不是将所有信息存放入一个字段中,避免在查询时的二次解析。

结语:以上就是首席CTO笔记为大家整理的关于django中filter中怎么使用或者的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于django中filter中怎么使用或者的相关内容别忘了在本站进行查找喔。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Python/18534.html