Django中查询表的具体字段(models的具体属性)

Django是一个ORM框架,这也就使得开发者不需要写SQL,而是通过一些封装好的API就可以进行数据库操作,省去了关于各种数据库的细节问题。

get, all, filter

一直以来,在Django中通过Model进行数据库查询的时候用的最多的就是get、all和filter,比如

1
_ = ExampleModel.objects.all()

这样得到的返回结果是一个QuerySet, 里面的元素是Model对象,而且返回的是对应的表中全部字段,类似于SQL中SELECT * FROM ......查询。如果业务需要如此的时候这么做当然没有问题,但是当业务不需要这么多数据的时候这么做就有两个问题:

  1. 查询所有字段会占用大量的内存,尤其数据库表中数据量非常大的时候这会成为性能瓶颈
  2. 没有直接获取到想要的数据,需要另外写代码过滤数据,浪费精力,写的代码还不一定好
    Django本身其实提供了方法简便地获取具体的字段的内容。

备注:
关于这两点其实不是绝对的,尤其是在数据量和并发都超大的场景下。
Django中Model的查询API最终其实也是转化成SQL来执行的,API复杂的时候也就意味的SQL复杂,这样就等于把计算压力从代码所在的服务器转嫁到了数据库服务器上,当数据量和并发(尤其是并发)巨大的时候,数据库服务器肯定不能承受,所以这个时候也许只能做简单的查询,然后通过自己写代码来做数据过滤和拼接


values、values_list

今天写一个功能的时候需要查询一个模型的一个指定的属性的值,以前其实也有类似的情况,但是一般就直接通过all或者filter来查询,然后自己过滤数据了,但是今天由于知道这张表以后的数据量会非常大(每分钟会新产生大约5000-7000条数据),如果依然像之前一样采用all或者filter就会出问题,所以就发现了values和valuies_list这两个方法。

  • values
    values方法获取指定属性时需要传入属性名

    1
    2
    3
    _ = ExampleModel.objects.values('id', 'username')
    # 返回的结果是QuerySet, 里面的元素是dict格式
    # [{'id':1, 'username': 'Austin'}, {'id':2, 'username':'Sam'}, ...]

    相当于SQL中的SELECT id, username FROM ......, 只返回对应属性(字段)的值,

  • values_list
    与values非常像,只是返回的QuerySet中的元素是tuple格式的

    1
    2
    3
    _ = ExampleModel.objects.values_list('id', 'username')
    # 返回的结果是QuerySet, 里面的元素是dict格式
    # [(1, 'Austin'), (2, 'Sam') ...]
  • 获取字符串格式的返回值
    当只需要获取一个属性的值时,可以通过制定flat=True来获得字符串格式的返回值,这往往更符合需求

    1
    2
    3
    _ = ExampleModel.objects.values_list('username', flat=True)
    # 获得返回值如下:
    # <QuerySet['Austin', 'Sam', ... ]>

官网链接: https://docs.djangoproject.com/en/3.1/ref/models/querysets/#django.db.models.query.QuerySet.values