Django之ORM操作(基础部分)
一、准备工作
第一步:创建数据库(以MySQL数据库为例)
创建时一定要指定数据库的编码格式,否则存入数据时会报错。
mysql> CREATE DATABASE mysite DEFAULT CHARACTER SET utf8;
第二步:配置数据库连接信息
配置文件:mysitemysitesettinDATABASES = {
'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': "mysite", # 数据库名称 "USER":"root", # 连接数据库的用户名 "PASSWORD":"Admin@123!", # 连接数据库的密码 "HOST": "127.0.0.1", # 数据库的IP地址 "POST":"3306", # 数据库的端口,mysql默认为3306 } }
第三步:安装pymysql
不装pymysql会报错
windows下安装方法:管理员身份运行cmd然后运行 pip3 install pymysql
在django中配置:mysitemysite\__init__.py
import pymysql pymysql.install_as_MySQLdb()
二、使用方法
1.创建表
创建表的代码都写在mysiteappmodels.py文件下from django.db import models
# Create your models here. # 账号信息表 class Userinfo(models.Model): username = models.CharField(max_length=30, verbose_name="账号") password = models.CharField(max_length=255, verbose_name="密码") email = models.EmailField(max_length=254, verbose_name="邮箱",null=True) registration_time = models.DateTimeField(auto_now_add=True,verbose_name="注册时间") mobile_phone = models.CharField(max_length=11,verbose_name="电话",null=True) account_status = models.ForeignKey("Account_status",on_delete=None) role = models.ManyToManyField("Role") def __str__(self): return self.username # 账号状态表 class Account_status(models.Model): account_status = models.CharField(max_length=20,verbose_name="账号状态") # def __str__(self): # return self.account_status # 账号角色表 class Role(models.Model): role_name = models.CharField(max_length=20, verbose_name="角色") comment = models.CharField(max_length=255,null=True) def __str__(self): return self.role_name # 主机列表信息表 class Machinelist(models.Model): hostname = models.CharField(max_length=30,verbose_name="主机名") os = models.CharField(max_length=30,verbose_name="操作系统") username = models.CharField(max_length=30,verbose_name="用户名") password = models.CharField(max_length=255,verbose_name="密码") ipaddress = models.GenericIPAddressField(verbose_name="IP地址") def __str__(self): return self.hostname # 主机所属的组 class Group(models.Model): group_name = models.CharField(max_length=30,verbose_name="组名")
hrough='Machine2Group', ## 自定义中间表
through_fields=('machine','group') # 第三张表中的字段
def __str__(self):
return self.group_name
# 自己创建主机和组的关联表(第三张表)
class Machine2Group(models.Model):
machine = models.ForeignKey("Machinelist", on_delete=None)
group = models.ForeignKey("Group",on_delete=None)
2.初始化数据库
python manage.py makemigrations #让修改动作保存到记录文件中
python manage.py migrate #让操作实际应用到数据库上
3.表的基本操作
关于表的操作都写在mysiteappviews.py文件下
3.1 create 增
3.1.1 单表操作 :2种方法4种方式
3.1.1.1 方法1:create()
方式1: 直接传值 models.Role.objects.create(role_name="admin",comment="管理员") 方式2: 传入一个字典 role={"role_name":"user","comment":"普通用户"} models.Role.objects.create(**role) 3.1.1.1 方法2:save() 方式1: 创建对象时赋值 stat1=models.Account_status(account_status="冻结") # 创建对象 stat1.save() # 执行save方法时才将将数据写入数据库 方式2: 先创建对象,然后赋值保存 stat2=models.Account_status() stat2.account_status="活跃" stat2.save()
3.1.2 多表操作
3.1.2.1 一对多: 方式一:直接赋值 models.Userinfo.objects.create(username="admin",password="123456",account_status_id=2) 方式二:先获取对象再赋值 stat_obj=models.Account_status.objects.get(account_status="活跃") #先从父表总获取对象 print(type(stat_obj)) print(stat_obj)
# 然后把对象赋值给子表中的字段 models.Userinfo.objects.create(username="zhangsan",password="123456",account_status=stat_obj) 3.1.2.1 多对多: A:Django自动创建第三张表的情况 使用add()方法 user = models.Userinfo.objects.get(username="admin") role = models.Role.objects.get(role_name="admin") user.role.add(role) #add(obj1,obj2,obj3) 可以传入多个对象 user = models.Userinfo.objects.filter(username="admin")//结果必须是一个可迭代对象 role = models.Role.objects.get(role_name="user") role.userinfo_set.add(*user) B:对于用户创建第三张表的情况 分别获取需要关联的对象,然后再第三张表中插入对象 格式:models.关联表.objects.create(字段名=对象,字段名=对象) machine_obj = models.Machinelist.objects.filter(id=1)[0] group_obj = models.Group.objects.filter(id=1)[0] models.Machine2Group.objects.create(machine=machine_obj,group=group_obj)
3.2 filter 查
3.2.1 单表查询
# 检索多个对象 # 返回所有对象,查询所有数据,可以使用切片指定返回的范围 print(models.Userinfo.objects.all()[:2]) # 过滤对象 host = models.Machinelist.objects.filter(hostname="localhost") print(models.Machinelist.objects.exclude(ipaddress="192.168.1.100")) # 检索一个对象:没有匹配到货匹配到多个都会报错 print(models.Machinelist.objects.get(ipaddress="192.168.1.100")) # 查询结果再处理 order_by() 对结果排序 reverse() 对查询结果反向排序 exists() 如果QuerySet包含数据,就返回True,否则返回False distinct() 从返回结果中剔除重复纪录 values() 返回字典序列,每一行的数据以字典的形式返回 values_list() 返回元组序列,每一行的数据以元组的形式返回 count() 返回数据库中匹配查询(QuerySet)的对象数量。 first() 返回第一条记录 last() 返回最后一条记录 # 双下划线 格式例:print(models.Group.objects.filter(id__in=[1,2])) 参数: __gt 大于 __lt 小于 __gte 大于或小于 __lte 小于或等于
__icontains 包含,对大小写敏感 __startwith __endwith
__istartwith __iendwith __range(start,end) __isnull
3.2.2 多表查询
3.2.2.1一对多 正向查询 # 查询admin用户的账户状态 print(models.Userinfo.objects.filter(username="admin").values("account_status__account_status")) 反向查询 print(models.Account_status.objects.filter(userinfo__username="admin").values("account_status")) 3.2.2.2多对多 正向查询 #通过用户表查询admin用户的角色 print(models.Userinfo.objects.filter(username="admin").values("role__comment")) 反向查询 #通过角色表查询admin角色下的用户 print(models.Role.objects.filter(userinfo__username="admin").values("comment")) 注:实验中发现只有系统自建的第三张表可以这样做
3.2.3 懒惰的queryset
用的时候才会触发SQL语句,已经执行过的放在缓存中
特点:可迭代,可切片,有缓存
缓存处理:当处理的数据量较大时,SQL执行的结果一次性放入内存会造成很大的压力。
解决方法:使用.iterator() 将对象变成变成迭代器
例: objs = models.Machinelist.objects.all() for obj in objs.iterator(): print(obj.hostname) 但是:每一次遍历都会执行一次SQL语句
3.2.4 分组查询与聚合查询
3.2.4.1 聚合查询aggregate(*args,**kwargs): from django.db.models import Avg,Min,Max,Sum print(models.Userinfo.objects.all().aggregate(Avg("id"))) 3.2.4.1 分组查询annotate(*args,**kwargs): from django.db.models import Avg,Min,Max,Sum print(models.Userinfo.objects.values("role__comment").annotate(Max("id")))
3.2.5 F查询与Q查询
3.2.5.1 F查询 对对象中的某列值进行操作 form django.db.models import F models.Book.objects.all().update(price=F("proce")+20) 加、减、乘、除、取模以及幂运算等算术操作 3.2.5.2 Q查询 复杂的查询 from django.db.models import Q # 查找用户名为admin或密码为123456的对象 print(models.Userinfo.objects.filter(Q(username="admin")| Q(password="123456")))
3.3 delete 删
.delete()
找到需要删除的对象,执行delete方法
3.4 update 改
3.4.1save 方法 admin = models.Userinfo.objects.get(username="admin") admin.password="admin@123!" admin.save() 3.4.2update 方法 models.Userinfo.objects.filter(username="zhangsan").update(password="zhangsan")