Django单表操作

一.Django 测试环境搭建

当你只是想测试django中的某一个py文件内容 那么你可以不用书写前后端交互的形式, 而是直接写一个测试脚本即可:

1.方式一

  • 使用脚本形式:任意创建一个 py 文件, 在该文件内书写固定的配置(可以去manage.py文件中去复制前四行)
# 测试环境的准备 去manage.py中拷贝前四行代码 然后自己写两行
import os
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Student_System.settings")
    import django
    django.setup()
    # 在这个代码块的下面就可以测试django里面的单个py文件了(注意: 导模块也要写在这下面)

img

2.方式二

  • 直接使用pycharm提供的Python console窗口

img

补充:

  1. 使用pycharm链接数据库都需要提前下载对应的驱动
  2. 自带的sqlite3对日期格式数据不敏感,如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3

二、单表查询关键字操作之增删改

1.准备表

# 在models.py文件准备表

class Books(models.Model):
    title = models.CharField(verbose_name='书名', max_length=32)
    price = models.DecimalField(verbose_name='价格', max_digits=8, decimal_places=2)
    publish_time = models.DateField(auto_now_add=True)
    '''
    auto_now:每次修改数据的时候都会自动更新当前时间
    auto_now_add:只在数据创建的时候记录一次创建时间,后续不会自动更改
    '''

# 然后使用数据库迁移同步命令
python3 manage.py makemigrations
manage.py migrate

2.增

#方式一:create方法
res = models.Books.objects.create(title='十年', price=9.9)

#方式二:创建对象再()save保存
ccd = models.Books(title='庆余年',price=18.1)
ccd.save()

3.删

bool_obj = models.Books.objects.filter(title='十年', price=9.9).delete()方式一:delete方法
    row = models.Books.objects.all().delete()
    print(row)  # row 为影响的条数
    rows = models.Books.objects.filter(pk=2).delete() #删除主键字段为2的
方式二:获取对象再进行删除delete()
bool_obj = models.Books.objects.filter(title='十年', price=9.9).delete()

4.改

方式一:update()
    models.Books.objects.filter(title='创业邦').update(price=99)

方式二:get()获取对象再进行赋值再save()保存
    book_obj = models.Books.objects.get(pk=9)
    book_obj.price = 999.99
    book_obj.save()  # 效率低(所有字段重新写一遍)

补充:
    1.pk能够自动查找到当前表的主键字段 我们不需要查看当前表主键字段名
    2.get括号内可以放多个参数 默认是and关系  不推荐使用  条件不符合直接报错

三、QuerySet对象查询方法介绍与单表查询

1.QuerySet介绍

  • 数据库接口相关的接口(QuerySet API)

  • QuerySet对象它是一个生成器,也可以将其看成一个列表

  • ORM提供了13种查询API

2.ORM13种查询API介绍

1.all():查询所有结果

  • 返回QuerySet对象
  • .all( )取值的时候,不会一下子全部取出来, 而是每次只取21条 (LIMIT21)
    res = models.Books.objects.all()
    print(res)  # <QuerySet [<Books: Books object (9)>, <Books: Books object (10)>, <Books: Books object (12)>, <Books: Books object (13)>, <Books: Books object (15)>, <Books: Books object (16)>, <Books: Books object (18)>, <Books: Books object (19)>]>

2.filter(**kwargs):过滤

  • 返回QuerySet对象. 筛选出与所给筛选条件相匹配的数据对象
  • 不指定筛选条件则默认查询所有
  • 当结果不存在返回空的QuerySet对象, 布尔值为False
    res = models.Books.objects.filter(title='创业邦')
    print(res)  #<QuerySet [<Books: Books object (9)>, <Books: Books object (12)>, <Books: Books object (15)>, <Books: Books object (18)>]>

    bok_obj = models.Books.objects.filter()  # 筛选所有,等同于帅选所有
    print(bok_obj)  #<QuerySet [<Books: Books object (9)>, <Books: Books object (10)>, <Books: Books object (12)>, <Books: Books object (13)>, <Books: Books object (15)>, <Books: Books object (16)>, <Books: Books object (18)>, <Books: Books object (19)>]>

    book_obj = models.Books.objects.filter(pk=8888)
    print(book_obj, bool(book_obj))     #<QuerySet []> False

3.get( **kwargs ) : 筛选表中的数据对象

  • 直接获取数据对象
  • 只能指定一个筛选条件,如果指定的筛选条件返回的结果不唯一 或者不存在抛出异常
    book_get_queryset = models.Books.objects.get(pk=10)
    print(book_get_queryset)  # Books object (10)

条件不存在抛出异常    
    book_obj = models.Books.objects.get(pk=8888)    #app01.models.DoesNotExist: Books matching query does not exist.
    book_get_queryset = models.Books.objects.get(title='十年')    #get() returned more than one Books -- it returned 3!

4.last():最后一个对象

  • 获取QuerySet列表中最后一个数据对象.
  • 如果QuerySet对象为空, 再使用它返回None
    book_last_queryset = models.Books.objects.filter().last()
    print(book_last_queryset)   #Books object (22)

    book_last_queryset = models.Books.objects.filter(pk=999).last()
    print(book_last_queryset)  # None

5.first( ) : 第一个对象

  • 直接获取QuerySet列表中第一个数据对象.
  • 如果QuerySet对象为空, 再使用它返回None
    book_first_last = models.Books.objects.filter(title='庆余年').first()
    print(book_first_last)  #Books object (10)

        book_first_queryset = models.Books.objects.filter(pk=8888).first()
    print(book_first_queryset)  #None

6.values(*field) :返回指定字段对象集

  • 返回QuerySet对象,内部是一种列表套字典的格式
  • 字典的key就是指定的字段名,指定字段若不存在抛出异常
    book_values_queryset=models.Books.objects.values('title','price')
    print(book_values_queryset)     #<QuerySet [{'title': '创业邦', 'price': Decimal('999.99')},,... {'title': '十年', 'price': Decimal('9.90')}]>

    #注意:指定字段不存在抛出异常
    book_values_queryset = models.Books.objects.values('xxxx')
    print(book_values_queryset) #django.core.exceptions.FieldError: Cannot resolve keyword 'xxxx' into field. Choices are: id, price, publish_time, title

7.values_list(*field):返回指定字段对象集

  • 返回QuerySet对象, 内部是一种列表套元组的格式
  • 字典的key就是指定的字段名,指定字段不存在就抛出异常
    book_values_queryset = models.Books.objects.values_list('title', 'price')
    print(book_values_queryset) #<QuerySet [('创业邦', Decimal('999.99')), ... ('十年', Decimal('9.90'))]>

#指定字段不存在就抛出异常
        book_values_queryset = models.Books.objects.values_list('xxx')
    print(book_values_queryset)     #django.core.exceptions.FieldError: Cannot resolve keyword 'xxx' into field. Choices are: id, price, publish_time, title

8.distinct():去重

  • 注意: 必须排除主键字段 或 唯一字段才会有意义
  • 要排除使用filter无法晒选,一般用在.values().value_list()后面
    book_values_queryset = models.Books.objects.values_list('title')
    dis_book_queryset = book_values_queryset.distinct()
    print(dis_book_queryset)    #<QuerySet [('创业邦',), ('庆余年',), ('十年',)]>

9.order_by(*field):排序

  • 对查询结果进行指定字段的排序
  • 默认升序. 如果想要降序在对应要查询的字段前指定-
    book_order_by=models.Books.objects.values('title').order_by('title')    #默认升序
    book_order_by=models.Books.objects.values('title').order_by('-title')    # - 号降序
book_order_by =models.Books.objects.all().order_by('title')
book_order_by = models.Books.objects.all().order_by('-age')

10.reverse( ) : 排序

  • 对查询结果进行反向排序
  • 反转的前提是数据已经排过序. 没排过序reverse将不起作用.
    book_reverse = models.Books.objects.all().order_by('title').reverse() #先进行排序,在反转
    book_reverse = models.Books.objects.all().order_by('-title').reverse()

11.count():统计个数

  • 查询QuerySet内部所包含的数据对象的个数
    book_count =models.Books.objects.filter().count()
    print(book_count)   # 11
    bok_count = models.Books.objects.all().count()
    print(bok_count)    # 11

12.exclude( **kwargs ) : 筛选出不匹配的对象

  • 查询与所给筛选条件不匹配的对象, 类似于取反
book_exclude=models.Books.objects.exclude(title='庆余年')
print(book_exclude)

13..exists( ) : 判断数据是否存在

  • 如果QuerySet包含数据, 就返回True, 否则返回False
    book_exists = models.Books.objects.filter(title='创业邦', price=99).exists()
    print(book_exists)  # True
    box_exists = models.Books.objects.filter(title='青年杂志').exists()
    print(box_exists)  # False

3.小结

# 返回QuerySet对象的方法
    .all()          获取所有.
    .filter()       过滤. 不指定参数获取所有. 查询结果不存在返回空的QuerySet对象, 布尔值False
    .distinct()     去重. 必须排除主键字段 或 唯一字段才会有意义. filter无法筛选, 一般用在.values() 或 .value_list()后面
    .order_by()     排序. 默认升序. 指定降序在字段前加`-`
    .reverse()      反转. 只能对排序过后进行反转. 必须在.order_by()之后.
    .exclude()      排除. 排除指定的, 展示所有.

# 返回特殊QuerySet对象的方法
    .values()       返回QuerySet之内部列表套字典格式. 字典key就是指定的字段.
    .values_list()   返回QuerySet之内部列表套元组格式. 元组中值就是指定字段对应的值, 按照指定字段顺序显示.
    注意!!!: 指定的字段不存在, 将会抛出异常

# 返回数据对象的方法
    .get()          直接获取数据对象. 只能指定一个筛选条件. 如果指定的筛选条件返回的结果不唯一 或者 不存在 抛出异常
    .first()        获取QuerySet对象列表内第一个值.  用在QuerySet对象之后, 如果QuerySet对象为空, 再使用它返回None
    .last()         获取QuerySet对象列表内最后一个值. 用在QuerySet对象之后, 如果QuerySet对象为空, 再使用它返回None

# 返回数字的方法
    .count()        统计QuerySet对象列表内数据对象的个数

# 返回布尔值的方法
    .exist()        没软用

四、单表查询之神奇的双下划线(范围查询)

1.参数介绍

参数 释义
__in 是否在给定的数据集中
__gt 大于
__lt 小于
__gte 大于等于
__lte 小于等于
__range 在...之间, 闭区间
__contains 包含
__icontains 包含(忽略大小写)
__startswith 以...开头
__endswith 以...结尾
__year 取出年份(仅限于时间类型)
__month 取出月份(仅限于时间类型)
__day 取出日期(仅限于时间类型)
__hour 取出小时(仅限于时间类型)
__minute 取出分钟(仅限于时间类型)
__second 取出秒(仅限于时间类型)
__week_day 一周的第几天(仅限于时间类型)

2.示例

# 1.查询价格大于100的书籍
    res = models.Books.objects.filter(price__gt=100)
    print(res)
    print(res.query)
# 2.查询价格小于100的书籍
    res = models.Books.objects.filter(price__lt=100)
    print(res)
    print(res.query)
# 价格大于等于99 小于等于99
    res1 = models.Books.objects.filter(price__gte=99)
    res2 = models.Books.objects.filter(price__lte=99)
    print(res1.query, res2.query)
# 3.查询价格要么是9.9要么是999.66 要么是1999
    res = models.Books.objects.filter(price__in=[9.9, 99.99, 1999])
    print(res)
    """python对数字不是很敏感 精确度不高  很多时候我们会采取字符串存储数字类型"""
# 4.查询价格在200到1000之间的
    res = models.Books.objects.filter(price__range=(200,1000))
    print(res.query)
# 5.查询书名中包含字母s的书
    res = models.Books.objects.filter(title__contains='s')  # 区分大小写
    print(res.query)
    res = models.Books.objects.filter(title__icontains='s')  # 区分大小写
    print(res)
# 6.查询出版日期是2021的书
    res = models.Books.objects.filter(publish_time__year=2021)
    print(res.query)
# 7.查询出版日期是3月的书
    res = models.Books.objects.filter(publish_time__month=3)
    print(res)

3.小结

# 注意: 争对字段使用. 如: field__gt
__gt __lt __gte __glt
__in=[]        __range=[start, stop]
__contains     __icontains  i全称忽略ignore
__startswith   __istartswith
__endswith     __iendswith
__year='2020'  __year=2020
__month='1'    __month=1
__day='20'     __day=20

五.拓展

1.查看内部封装的sql语句的2种形式

# 第一种: QuerySet.query
user_queryset = models.User.objects.values_list('name', 'age')
print(user_queryset.query)  # SELECT `app01_user`.`name`, `app01_user`.`age` FROM `app01_user`

# 第二种: 执行脚本时打印日志显示到终端. 复制以下日志内容到settings.py中
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

2.QuerySet其他特性

QuerySet 是可迭代的,比如:

es = models.Books.objects.all()
for e in es:
    print({'书名': e.title, '价格': e.price})

QuerySet 支持切片 Entry.objects.all()[:10] 取出10条,可以节省内存

es = models.Books.objects.all()[:2]
print(es)   # <QuerySet [<Books: Books object (9)>, <Books: Books object (10)>]>

用 len(es) 可以得到Entry的数量,但是推荐用 Entry.objects.count()来查询数量

es = models.Books.objects.all()
print(len(es))

list(es) 可以强行将 QuerySet 变成 列表

    es = models.Books.objects.all()[:2] #前两条
    print(list(es))

QuerySet 不支持负索引

    book_index = models.Books.objects.all().reverse()[:2]  # 最后两条
    print(book_index)
    box_index = models.Books.objects.filter().reverse()[0]  # 最后一条
    print(box_index)
    bok_index =models.Books.objects.order_by('-price')[:1]
    print(bok_index)

QuerySet 是可以用pickle序列化到硬盘再读取出来的

>>> import pickle
>>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query            # Restore the original 'query'.

版权声明:
作者:淘小欣
链接:https://blog.taoxiaoxin.club/150.html
来源:淘小欣的博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
Django单表操作
一.Django 测试环境搭建 当你只是想测试django中的某一个py文件内容 那么你可以不用书写前后端交互的形式, 而是直接写一个测试脚本即可: 1.方式一 使用脚本形……
<<上一篇
下一篇>>