模型查询

查询集表示从数据库获取的对象集合

查询集可以有多个过滤器,filter,exclude
过滤器就是一个函数,基于所给的参数限制查询集结果
从SQL角度来说,查询集合和select语句等价,过滤器就像where条件

查询集和过滤器


在管理器上调用方法返回查询集
查询经过过滤器筛选后返回新的查询集,所以可以写成链式调用
返回查询集的方法称为过滤器

all()  返回所有数据

filter()  返回符合条件的数据

exclude()  过滤掉符合条件的数据

order_by()  排序

views中:

def get_persons(request):
    # __gt大于,__lt小于
    # 筛选出大于18小于80的人的姓名和年龄
    # persons = Person.objects.filter(p_age__gt=18).filter(p_age__lt=80)
    # 筛选出大于等于50的,及排除小于50的,并且小于80的
    # persons = Person.objects.exclude(p_age__lt=50).filter(p_age__lt=80)
    #all()取出所有数据,order_by()排序,而-id指的是按照id倒序排列
    persons = Person.objects.all().order_by('-id')
    # 填坑
    context = {
        'persons': persons
    }
    return render(request, 'person_list.html', context=context)

  #all()取出所有数据,order_by()排序,而-id指的是按照id倒序排列

values()  一条数据就是一个字典,返回一个列表

views中:

ef get_persons(request):
    # __gt大于,__lt小于
    # 筛选出大于18小于80的人的姓名和年龄
    # persons = Person.objects.filter(p_age__gt=18).filter(p_age__lt=80)
    # 筛选出大于等于50的,及排除小于50的,并且小于80的
    # persons = Person.objects.exclude(p_age__lt=50).filter(p_age__lt=80)
    persons = Person.objects.all().order_by('-id')
    persons_values = persons.values()
    print(type(persons_values))
    print(persons_values)

9行打印类型
10行打应

运行之后我们可以看到.values的类型是查询集
内容是字典,类似于josn文件格式
我们可以转换成json,(json可以与前端移动端对接)

返回单个数据


get():返回一个满足条件的对象

  • 查询条件没有匹配的对象,会抛异常,DoesNotExist
    - 如果查询条件对应多个对象,会抛异常,MultipleObjectsReturned
    所以由于经常异常,所以我们需要使用try except提高兼容性

    first():返回查询集中的第一个对象

def get_person(request):
    person = Person.objects.first()
    print(person.p_name)
    return HttpResponse('获取成功')

last():返回查询集中的最后一个对象

first和last

  • 默认情况下可以正常从QuerySet中获取
    隐藏bug
     - 可能会出现 first和last获取到的是相同的对象
    解决方法:手动写order_by之后再去调用last ,first

    count():返回当前查询集中的对象个数

    演示:
    新建应用two,注册,urls
    新建model

    from django.db import models
    
    
    class User(models.Model):
      u_name = models.CharField(max_length=16, unique=True)
      u_name = models.CharField(max_length=256)

    然后迁移
    之后view中添加函数:

    from two.models import User
    # 验证用户名密码对不对
    # 数据库中已经添加了用户名张三以及对应密码120
    
    def get_user(request):
      username = '张三'
      password = '120'
    
      users = User.objects.filter(u_name=username)
    
      print(users.count())
    
      if users.count():
          user = users.first()
          if user.u_password == password:
              print('获取用户信息成功')
          else:
              print('密码错误')
      else:
          print('用户不存在')
      return HttpResponse('获取成功')

    返回了获取成功,更换错误用户名或者密码,分别print对应信息
    count是获取数量,数量为零说明不存在该对象,如果数量大于1则说明存在该对象,我们可以用来做判断
    而exists直接用来做判断

    exists():判断查询集中是否有数据,如果有数据返回True没有反之

    状态码

  • 2xx
     - 请求成功
    - 3xx
     - 转发或重定向,你请求我我转发到其他地方
    - 4xx
     - 客户端错误
    - 5xx
     - 服务器错了
     - 后端开发人员最不想看到的,有也要想办法不显示

    限制查询集和查询集的缓存


    切片

    左闭右开

  • 和python中的切片不太一样,不会直接加载到内存中再进行切片
  • QuerySet[5:15]  获取第五条到第十五条数据

    • 相当于SQL中limit和offset


限制查询集,可以使用下标的方法进行限制,等同于sql中limit
studentList = Student.objects.all()[0:5] 
  下标不能是负数

操作:添加url('getusers/', views.get_users),
views中:第二行使用了切片

def get_users(request):
    users = User.objects.all()[1:3]
    context = {
        'users': users
    }
    return render(request, 'user_list.html',context=context)

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>userlist</title>
</head>
<body>
<h3>userlist</h3>
<hr>
<ul>
{% for user in users %}
    <li>{{ user.u_name }}</li>
{% endfor %}



</ul>
</body>
</html>

查询:

查询集的缓存:每个查询集都包含一个缓存,来最小化对数据库的访问
查单个对象属性,或者for循环的时候才会真正去查这个库

缓存集

  • filter
  • exclude
  • all
  • 都不会真正的去查询数据库
  • 只有我们在迭代结果集,或者获取单个对象属性的时候,它才会去查询数据库
  • 懒查询

    • 为了优化我们结构和查询

在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存,django会将查询出来的数据做一个缓存,并返回查询结构,以后的查询直接使用查询集的缓存。

最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏