24 ORM单表操作


1 前期准备
2 数据的增删改查
3 必知必会13条
4 QuerySet类型
5 查看内部sql语句的方式
6 神奇的双下划线查询
7 批量插入

django自带的sqlite3数据库对日期格式不是很敏感 处理的时候容易出错

我们使用mysql

一、 前期准备

1.1 新建名为app01的app,在app01的models.py中创建模型

from django.db import models
class Book(models.Model)
title=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=8,decimal_places=2)
publish_date=models.DateField(auto_now_add=True) #年月日
    def __str__(self):
return self.title
 """ DateField DateTimeField 
两个重要参数
auto_now:每次操作数据,该字段会自动将当前时间更新
auto_now_add:在创建数据的时候会自动将当前时间记录下来,之后只有不人为修改,那么就一直不变

1.2 django的orm支持多种数据库,如果想将上述模型转为mysql数据库中的表,需要settings.py中

# 删除\注释掉原来的DATABASES配置项,新增下述配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # 使用mysql数据库
        'NAME': 'db1',          # 要连接的数据库
        'USER': 'root',         # 链接数据库的用于名
        'PASSWORD': '',         # 链接数据库的用于名                  
        'HOST': '127.0.0.1',    # mysql服务监听的ip  
        'PORT': 3306,           # mysql服务监听的端口  
        'ATOMIC_REQUEST': True, #设置为True代表同一个http请求所对应的所有sql都放在一个事务中执行 
                                #(要么所有都成功,要么所有都失败),这是全局性的配置,如果要对某个
                                #http请求放水(然后自定义事务),可以用non_atomic_requests修饰器 
        'OPTIONS': {
            'init_command': 'SET sql_mode="STRICT_TRANS_TABLES"',
        }
    }
}

1.3 修改django的orm默认操作数据库的模块为pymysql

import pymysql
pymysql.install_as_MySQLdb()

1.4数据库迁移

python manage.py makemigrations
python manage.py migrate

 

2、测试环境

方法一:pycharm自动提供的python console

方法二:py文件形式(随便建在哪里,参考manage.py前四行)

去manage.py中拷贝前四行代码 然后自己写两行

import os
if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'day59.settings')
    import django
    django.setup()   # 在该代码的下方才可以正常测试django文件
    from app01 import models
    print(models.Book.objects.all())

二、数据的增删改查

   1.增

方法一:

user_obj = models.User.objects.create(name='dzg',age=18)

方法二:

user_obj = models.User(name='dd',age=19)
user_obj.save()

pk会自动查找到当前表的主键字段 指代的就是当前表的主键字段

用了pk之后 你就不需要指代当前表的主键字段到底叫什么了

 方式一:可以用来批量删除

res = models.User.objects.filter(pk=2).delete()
print(res)  #(1, {'app01.User': 1})

方式二:

user_obj = models.User.objects.filter(pk=1).first()
user_obj.delete()

方式一:

models.User.objects.filter(pk=4).update(name="dzg66")

方式二:

user_obj = models.User.objects.filter(pk=4).first()
user_obj.name = "dzg111"
user_obj.save()

必知必会13条

   1.all()   #查看所有的数据
     res = models.Books.objects.all()  # QuerySet
     print(res)
     print(res.first())
     print(res.last())
     print(res[1])
    '''queryset支持正数的索引取值'''
    print(res)

2.filter() res = models.Books.objects.filter(id=1) QuerySet '''pk能够自动定位当前表的主键字段 避免了你自己去频繁查看''' res = models.Books.objects.filter(pk=2) QuerySet print(res) '''filter括号内可以存放多个条件默认是and关系''' res = models.Books.objects.filter(pk=2,title='jpm') 不存在,返回 print(res)

3.values() '''values可以指定查询的字段 结果QuerySet 列表套字典''' res = models.Books.objects.values('title','price')

4.values_list() '''values_list也可以指定查询的字段 结果QuerySet 列表套元组''' res = models.Books.objects.values_list('title', 'price') print(res)
      查看内部封装的sql语句
      上述查看sql语句的方式  只能用于queryset对象
      只有queryset对象才能够点击query查看内部的sql语句


5.first()与last() 分别获取queryset第一个和最后一个数据对象 res = models.Books.objects.all().filter().values('title','price') print(res) '''只要是queryset对象 就可以无限制的调用queryset对象的方法'''

6.get() 不推荐使用 res = models.Books.objects.get(pk=1) '''get方法可以直接获取到数据对象''' print(res,res.pk,res.title,res.price,res.publish_time) '''但是该方法当查询条件不存在的时候会直接报错 没有filter好用!!!''' res = models.Books.objects.get(pk=100) #pk不存在,报错 res1 = models.Books.objects.filter(pk=100) #用filter,当pk不存在时返回 print(res1)

7.exclude() 取反 QuerySet 列表套数据对象 res = models.Books.objects.exclude(pk=1) print(res)

8.order_by() 排序 QuerySet 列表套数据对象 res = models.Books.objects.order_by('price') print(res)

9.reverse() 翻转(必须提前有顺序才可以) res = models.Books.objects.all() print(res) print(res.order_by('price')) print(res.order_by('price').reverse())

10.distinct() 去重 '''尤其要注意主键字段''' res = models.Books.objects.all().values('title','price') print(res) print(res.distinct())

11.count() 计数 res = models.Books.objects.all().count() res1 = models.Books.objects.count() print(res, res1) # 4 4

12.exists() 判断结果集是否有数据(不需要使用) res = models.Books.objects.all().exists() res1 = models.Books.objects.filter(id=100).exists() print(res,res1) # True False

13.create()、update()、delete()、对象.save()

如何查看SQL语句

1.如果当前对象是queryset那么可以直接点query查找该对象内部SQL语句
res = models.User.objects.filter(pk=3)
print(res.query)
2.settings配置文件最下面加上下面的配置(只要执行orm语句都会自动打印SQL语句)

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}

 

神奇的双下划线查询

# 神奇双下划綫查询
    # 1.查询价格大于800的书籍
    # res = models.Books.objects.filter(price__gt=800)
    # print(res)

# 2.查询价格小于800的书籍 # res = models.Books.objects.filter(price__lt=800) # print(res)

# 3.查询价格大于等于800的书籍 # res = models.Books.objects.filter(price__gte=800) # print(res)

# 4.查询价格大于等于800的书籍 # res = models.Books.objects.filter(price__lte=800) # print(res)

# 5.查询价格是989.45 或者278.89 或者888.21 # res = models.Books.objects.filter(price__in=["888.21","278.89","989.45"]) # print(res)

# 6.查询价格在200到800之间的书籍 # res = models.Books.objects.filter(price__range=(200,800)) # print(res)

# 7.查询书籍名称中包含字母p的书(区分大小写) # res = models.Books.objects.filter(title__contains='p') # print(res) # res = models.Books.objects.filter(title__icontains='p') #contains前面加i 忽略大小写 # print(res)

# 8.查询书籍是否以...开头 ...结尾 # res = models.Books.objects.filter(title__startswith=“j”) # res1 = models.Books.objects.filter(title__endswith=“T”)

# 9.查询出版日期是2021的书(常用) res = models.Books.objects.filter(publish_time__year=2021) res1 = models.Books.objects.filter(publish_time__month=11) print(res,res1)