django模型层详解
- 自带的sqlate3数据库对时间字段不敏感 有时候会展示错乱所以我们习惯切换成常见的数据库比如MYSQL
django orm并不会帮我们创建数据库 所以需要我们自己提前创建好数据库
配置好settings文件数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djg07',
'HOST': 'localhost',
'PORT': 3306,
'USER': 'root',
'PASSWORD': 'root',
'CHARTSET': 'utf8'
}
}
准备好表
class User(models.Model):
id = models.AutoField(primary_key=True, verbose_name='用户id')
name = models.CharField(max_length=32, verbose_name='姓名')
age = models.IntegerField(verbose_name='年龄')
register_time = models.DateTimeField(verbose_name='注册时间', auto_now_add=True)
# auto_now 是只要修改或添加就会把当前时间自动更新
# auto_now_add 是在增加第一次创建数据时自动把当前时间添加到里面
# models.DateTimeField年月日时分秒时间 models.DateField 年月日时间
def __str__(self):
# 在打印类产生的方法时触发,只能返回字符串数据
return f'对象:{self.name}'
-
单独测试django某个功能层
默认不允许单独测试某个py文件
-
如果想要测试某个py文件(主要models.py)
#需要把这个放在最顶上 import os import django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django07.settings') django.setup() #测试的数据一定要放在他们下面,否则会跟上面报错一样无法正常测试 from user import models models.User.objects.create(name='张三', age=18)
-
django orm底层还是SQL语句我们是可以查看的
如果我们手上是一个QuerySet对象 那么可以直接点query查看SQL语句
但是有的orm提供的方法不是一个QuerySet对象,但是又想看SQL语句那么也可以在配置文件中添加日志记录的
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', }, } }
ORM常用关键字(方法)
-
创建数据create() 创建数据并直接获取当前创建的数据对象
res = models.User.objects.create(name='张三', age=18) print(res) res = models.User.objects.create(name='李四', age=28) print(res) res = models.User.objects.create(name='jason', age=18) print(res) res = models.User.objects.create(name='tom', age=38) print(res) res = models.User.objects.create(name='jerry', age=88) print(res) res = models.User.objects.create(name='ikun', age=58) print(res)
-
筛选数据filter() 根据条件筛选数据 结果是QuerySet[对象1,对象2,···]
res = models.User.objects.filter() # 不写默认就算查所有字段 print(res) res = models.User.objects.filter(name='jason') # 写了就根据字段名与字段值查找数据 print(res) res = models.User.objects.filter(name='jason',age=18) # 可以写多个筛选条件,默认是and连接 print(res)
-
first() last() QuerySet支持索引取值但是只能只正数 并且ORM不建议我们使用索引
res = models.User.objects.filter() print(res[0]) res = models.User.objects.filter(id=100) print(res[0])
# 无法执行 res = models.User.objects.filter() print(res[-1]) assert ((not isinstance(k, slice) and (k >= 0)) or AssertionError: Negative indexing is not supported.
使用first,与last去索引
res = models.User.objects.filter() print(res.first()) print(res.last()) res = models.User.objects.filter(id=1000) print(res.first()) # 数据不存在索引取值也不会报错 print(res.last())
-
更新数据update (批量更新数据)
models.User.objects.update() # 批量更新数据 res = models.User.objects.filter(id=1).update(name='托马斯') # 手动筛选数据,在更新达到指定更新的效果 print(res) # update返回的是影响行数
-
删除数据delete (批量删除)
# models.User.objects.delete() # 批量删除数据 res = models.User.objects.filter(id=1).delete() # 手动筛选数据,进行删,我们一般都不会进行删除数据只会修改数据字段已达到删除的目的 print(res)
-
查询所有数据all 结果是QuerySet[对象1,对象2]
res = models.User.objects.all() # 查询所有数据django默认查询全部的时候,查21条,需要了在继续查 print(res)
-
获取字段数据values 结果是QuerySet[{},{},{}]
res = models.User.objects.values() # 获取所有数据字段所有值 print(res) print(res.first().get('name')) # 这里又重新查了一般数据库 """ (0.000) SELECT `user_user`.`id`, `user_user`.`name`, `user_user`.`age`, `user_user`.`register_time` FROM `user_user` ORDER BY `user_user`.`id` ASC LIMIT 1; args=() """ res = models.User.objects.all().values('name') # 获取全部数据name字段 print(res) res = models.User.objects.filter(id=4).values('name') # 过滤数据后在获取name字段数据 print(res)
-
values_list 根据指定字段获取数据结果QuerySet[(),(),()]
res = models.User.objects.filter(id=3).values_list('name', 'age') print(res)
-
去重distinct 数据一模一样才可以去重如果有主键肯定不行
res = models.User.objects.values('name', 'age').distinct() print(res) """ <QuerySet [{'name': '李四', 'age': 28}, {'name': 'jason', 'age': 18}, {'name': 'tom', 'age': 38}, {'name': 'jerry', 'age': 88}, {'name': 'ikun', 'age': 58}]> """ res = models.User.objects.values('name', 'age').distinct('age') print(res)
-
排序oredr_by()
res = models.User.objects.all().order_by('age','id') # 默认为升序 print(res) res = models.User.objects.all().order_by('-age','id') # 字段前面加-号就是降序 print(res)
-
get() 根据条件筛选数据并直接获取到对象一旦条件不存在会直接报错 不建议使用
res = models.User.objects.get(pk=2) # 有数据能查到,执行 print(res) res = models.User.objects.get(pk=1) # 没有数据查新报错 print(res)
-
取反操作exclude() 是除了当前指定筛选数据不查询,查询其他的
res = models.User.objects.exclude(pk=2) # 是除了当前指定筛选数据不查询,查询其他的 print(res) res = models.User.objects.all() print(res)
-
reverse() 颠倒顺序(被操作的对象必须是已经排过序的才可以)
res = models.User.objects.all().order_by('id').reverse() # 颠倒排序 print(res) res = models.User.objects.all().order_by('id') # 升序 print(res) res = models.User.objects.all().reverse() # 没有排序颠倒不生效 print(res)
-
count() 统计结果中数据的个数
res = models.User.objects.filter(age=18).count() # 返回值为统计个数 print(res)
-
exists() 判断结果集中是否含有数据 如果有则返回Ture 没有则返回False
res = models.User.objects.all().exists() print(res) res = models.User.objects.filter(pk=100).exists() print(res)