欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Django知识点:ORM操作

程序员文章站 2022-05-31 20:46:28
...

字段类型

CharFiled 字符串类型,需要指定长度
IntegerField 整型
FloatField 浮点型
DateField 日期,年月日
DateTimeField 年月日时分秒
BooleanField 布尔
TextField 文本
EmailField 邮箱
DecimalField 浮点,指定小数点位数decimal_places,和长度max_digits
ForeignKey 外键
ImageField 图片类型,需要依赖 pillow,能够完成图片的上传

ImageField 字段使用:

在settings 中增加配置,决定图片上传的路径
MEDIA_URL = 'media'
MEDIA_ROOT = os.path.join(BASE_DIR,'static')

单表操作

已有数据模型

class User(models.Model):
    # id = models.AutoField(primary_key=True)  # 主键
    name = models.CharField(max_length=32, verbose_name="姓名")   # 名字,字符串
    age = models.IntegerField(verbose_name="年龄")                # 年龄 int
    gender = models.CharField(max_length=4, verbose_name="性别")  # 性别  int

方法 注释,语法 返回值
save 先实例化对象user,user.属性 = 值… user.save()添加数据
create 先定义一个操作字典,包含属性和对应的值,调用create方法添加数据
all 查询所有数据,可以通过下标获取对象,然后在(.属性)获取对象属性的值 queryset 列表对象
get 获取符合条件的数据,有且只有一条,否在报错,通常配合id 使用 对象
filter 类似sql中的where,过滤的作用,返回所有符合条件的数据 queryset
first 操作的是queryset ,返回第一条数据 对象
exclude 返回不符合条件的数据 queryset
order_by 对拿到的数据排序,默认顺序是正序,order_by(’-id’)是对id逆序,操作的是queryset queryset
values 返回的是一个类 queryset 里面的数据字典类型 queryset类字典类型
exists 判断数据是否存在 布尔值
count 统计符合条件的数据条数 数字
切片 [ ] 对拿到的数据二次操作 queryset列表对象
update 是queryset 的一个方法,如果是对象不能使用update
delete 删除数据,是queryset的一个方法,对象不能使用delete

双下划线语法:一般配合filter 使用

id__lt 小于
id__gt 大于
id__gte 大于等于
id__in=[1,2,3] id 在列表里的取值
contains 包含指定字符,大小写敏感
icontsins 包含指定字符,大小写不敏感
startswith 指定字符开头,大小写敏感
endswith 指定字符结尾,大小写敏感
iendswith 指定字符结尾,大小写不敏感
id__range(1,3) 在指定的范围,是一个前闭合,后闭合的区间,包含头和尾

增加数据

  1. save 方法
  • 方法1:先实例化对象user,在实例化的时候添加对象的属性,之后再用user对象调用save方法实现添加数据
def adduser(request):
	user = User(name='Ian',age=11,gender='nan')
	user.save()
  • 方法2:实例化对象user,一个一个的对象添加属性,之后再调用save方法实现添加数据
def adduser(request):
	user.User()
	user.name = 'ian'
	user.age = 12
	user.gender = 'nv'
	user.save()
  1. create 方法
  • create是一个方法
def adduser(request):
	# 方式1
	User.objects.create(name='Damon',age='13',gender='nan')
	# 方式2
	params = dict(name='Alaric',age=14,gender='nan')
	User.objects.create(**params)
ps:**  出现在形参中,是关键字参数
	**  出现在实参中是解包 的意思
	在这里的意思是:传入的params 是一个字典参数,将这个字典的键值对拆解出来,把拆解出来的参数当参数用

给表再添加几条数据

def adduser(request):
	user = User(name='Nina',age=15,gender='nv')
	user.save()
	
	User.objects.create(name='aaa',age=16,gender='nan')
	User.objects.create(name='aaa',age=26,gender='nv')
	User.objects.create(name='aaa',age=36,gender='nan')
	User.objects.create(name='bbb',age=17,gender='nv')
	
	params = dict(name='ccc',age=18,gender='nv')
	User.objects.create(**params)
	

查询方法

  1. all 方法
  • 查询所有的数据
  • 返回值:queryset 类列表对象
  • 要获取某一条数据用下标,或者遍历获取每一个
  • 获取某个对象的属性通过 “.属性”
def getuser(request):
	data = User.objects.all()
	# 打印的是全部数据,是一个类列表对象
	print(data)
	# 打印的是这个列表对象中下标为0的数据
	print(data[0])
	# 打印的是列表对象中下标为0的数据的name属性的值
	print(data[0].name)
	# for循环可以遍历获取每一条数据
	for i in data:
		print(i)  # i是个对象
		print(i[0].name)

  1. get 方法
  • 返回符合条件的数据,且返回结果有且只有一条数据,否则报错
  • 返回值:对象
  • get 通常用 id 作为条件
def getuser(request):
	# 拿到id为1的数据
	data = User.objects.get(id=1)
	print(data)
	# 拿到name为Alaric的数据
	data = User.objects.get(name='Alaric')
	print(data)
  1. filter 方法
  • 类似于sql中where,过滤的作用
  • 返回值:queryset
def getuser(request):
	data = User.objects.filter(name='Ian')
	# 打印name为Ian的数据
	print(data)
	# filter拿到的是一个类列表对象,可以用for遍历
	for i in data:
		print(i.id)
	# 当有多个条件的时候,条件之间是and关系,需要同时满足
	data = User.objects.filter(name='Ian',age=11)
	print(data)

  1. first 方法
  • 返回第一条数据
  • 返回值:对象
def getuser(request):
	# 通过filter获取的name为aaa的有三条数据,first获取第一条数据
	data = User.objects.filter(name='aaa').first()
	print(data)
  1. last 方法
  • 返回最后一条数据
  • 返回值:对象
def getuser(request):
	# 通过filter获取的name为aaa的有三条数据,last获取第一条数据
	data = User.objects.filter(name='aaa').last()
	print(data)
  1. exclude 方法
  • 返回不符合条件的数据(不包含条件属性的其他所有数据)
  • 返回值:queryset
def getuesr(request):
	# 查询所有gender为nan的所有数据(查询所有不是nv的数据)
	data = User.objects.exclude(gender='nv')
	print(data)
  1. order_by
  • 排序
  • 返回值:queryset
def getuser(request):
	# 升序
	data = User.objects.order_by('id','age')
	print(data)
	# 逆序
	data = User.objects.order_by('-id')
	print(data)
  1. reverse 方法
  • 对查询的结果反向排序,多个排序条件的话,前面的先排序
  • 返回值:queryest
data = User.objects.all().order_by('id').reverse()
print(data)
  1. values 方法
  • 返回一个类 queryset 里面的数据字典类型
  • 可以根据key(类属性)拿到对应的值
data = User.objects.all().values()  # 得到一个queryset类字典类型
data = User.objects.all().values('name','age')  # 根据属性关键字,拿到对应的属性的值
print(data)
  1. exists 方法
  • 判断这条数据是否在数据库存在
  • 返回值:布尔值 True,存在 False,不存在
flag = User.objects.filter(name='Ian').exists()
print(flag)
  1. count 方法
  • 统计符合条件的数据条数
  • 返回值:数字
num = User.objects.filter(name='damon').count()
print(num)
  1. 切片 [ ]
  • 对拿到的数据进行二次处理
  • 返回值:是对queryset 对象进行处理,所以拿到的是对象
data = User.objects.all()[1:3]
print(data)

修改数据

  1. save 方法
  • 需要先查询数据,拿到数据实例对象
  • 然后在修改实例对象的属性的值
  • save 方法保存数据
user = User.objects.filter(id=2).first()
user.age = 222
user.save()
  1. update 方法
  • 是 queryset 的方法,操作的不能是对象
User.objects.filter(id=4).update(age=555)
User.objects.filter(name='aaa').update(age=44)

删除数据

  1. delete 方法
  • 是queryset 的方法,操作的不能是对象
User.objects.filter(id=6).delete()
User.objects.filter(name='aaa').delete()

一对多操作

已有模型
Django知识点:ORM操作

添加数据

Publish.objects.create(name='北京出版社',address='北京')
Publish.objects.create(name='河南出版社',address='河南')
Publish.objects.create(name='山东出版社',address='山东')

# 第一种
Book.objects.create(name='python基础',publish_id=1)
# 第二种
publish = Publish.objects.get(name='北京出版社')
Book.objects.create(name='python开发',publish_id=publish.id)
# 第三种
publish = Publish.objects.get(name='河南出版社')
Book.objects.create(name='pythonWeb',publish=publish)
# 第四种
Book.objects.create(name='pythonWeb',publish=Publish.objects.get(name='山东出版社'))

# 正向:从外键所在的表到关联表的操作叫正向操作
book = Book()
book.name = 'py数据分析'
book.publish = Publish.objects.get(name='河南出版社')
book.save()

# 反向:从关联表到外键所在的表的操作
publish = Publish.objects.filter(name='山东出版社').first()
publish.book_set.create(name='py爬虫')

# 在创建出版社的时候,直接在后面添加该出版社的书籍
publish = Publish.objects.create(name='河南出版社')
publish.book_set.create(name='py技术')

查询

# 查询北京出版社的书籍
pub = Publish.objects.get(name='北京出版社')
book = Book.objects.filter(publish_id=pub.id).values('name')
book1 = Book.objects.filter(publish=pub).values('name')
print(book,book1)

# 查询python基础的出版社的名字
book = Book.objects.get(name='python基础')
pname = Publish.objects.get(id=book.publish_id)
print(pname.name)

# 正向查询  book->publish
# 查 python基础的出版社信息
book = Book.objects.get(name='python基础')
pub_name = book.publish.name  # book.publish得到的是一个出版社对象
print(pub_name)
pub_id = book.publish_id  # 直接拿book的publish_id就是对应出版社的id
print(pub_id)

# 反向查询:pub-》book
# 查北京出版社的书籍
pub = Publish.objects.get(name='北京出版社')
b_name = pub.book_set.all().values('name')
print(b_name)

修改数据

# 1.save   将python基础的出版社修改为河南出版社
book = Book.objects.get(name='python基础')
pub = Publish.objects.get(name='河南出版社',address='河南')
book.publish = pub
book.save()

# 2.update
pub = Publish.objects.get(name='北京出版社')
Book.objects.filter(name='py爬虫').update(publish = pub)

删除数据

  • 需要先删除外键所在的表,针对现有的表,只能删除书的数据,出版社的不能删
# 删除“python基础”
Book.objects.get(name='python基础').delete()

# 删除关联表  删除py爬虫的对应的出版社信息
book = Book.objects.get(name='py爬虫')
book.delete()

# 删除“py技术”
book = Book.objects.get(name='py技术')  # 实例化py技术这本书
Publish.objects.filter(id = book.publish_id).delete()  # Publish调用delete 方法删除

多对多操作

已有模板
Django知识点:ORM操作

添加数据

# 增加老师
Teacher.objects.create(name='老张',gender=1)
Teacher.objects.create(name='老王',gender=1)
Teacher.objects.create(name='老李',gender=1)
Teacher.objects.create(name='丽丽',gender=0)

# 增加学生
Student.objects.create(name='张一',age=21,gender=1)
Student.objects.create(name='张二',age=22,gender=1)
# 正向添加:王一想上老王的课
teacher = Teacher.objects.get(name='老王')  # 先实例化老师对象
teacher.student.create(name='王一',age=23,gender=1)  # 老师.学生.create方法
# 正向添加:小三和小四想上女老师的课
teacher = Teacher.objects.get(gender=0)  # 实例化老师对象
student1 = Student.objects.create(name='小三',age=31,gender=1)  # 实例化多个学生对象
student2 = Student.objects.create(name='小四',age=22,gender=0)
teacher.student.add(student1,student2)  # 老师.学生.add方法(学生1,学生2)
# 反向添加:小五想上老李的课
student = Student.objects.create(name='小五',age=25,gender=1)  # 实例化学生对象
teacher = Teacher.objects.filter(name='老李').first()  # 实例化老师对象
student.teacher_set.add(teacher)  # 学生.老师_set.add方法(老师)

查询数据

# 正向查询:老张的学生都有谁
teacher = Teacher.objects.filter(name='老张').first()  # 实例化老师对象
student = teacher.student.all().values('name')  # 老师.学生.all().values()
print(student)

# 反向查询:丽丽的学生都有谁
student = Student.objects.filter(name='小三').first()  # 实例化学生对象
teacher = student.teacher_set.all().values('name')  # 学生.老师_set.all().values(属性关键字)
print(teacher)

修改数据

  • 正向修改数据的时候用 set()方法
  • 反向修改数据的时候使用 _set()方法
  • 括号里面可以放多个对象,也可以是 [ id1 , id2 , id3 ]
# 正向
# 把学生id为3,4,5的学生老师都换成丽丽
teacher = Teacher.objects.get(name='丽丽')  # 实例化老师对象
teacher.student.set([3,4,5])  # 

# 反向
# 给小三选上老师id为1,2,3,4的课
student = Student.objects.get(name='小三')
student.teacher_set.set([1,2,3,4])

删除数据

  • remove 删除关系
  • remove() 可以加id,也可以加对象
  • clear 清空所有的关系
  • delete 删除数据之后,对应的关系表里的关系也没有了
# 正向:解除小四和丽丽的关系
# 正向删除的时候,直接调用remove方法
teacher = Teacher.objects.get(name='丽丽')
student = Student.objects.get(name='小四')
teacher.student.remove(student)
# 反向:解除丽丽和小三的关系
# 反向删除的时候,加个_set 再用remove 方法
teacher = Teacher.objects.get(name='丽丽')
student = Student.objects.get(name='小三')
student.teacher_set.remove(teacher)

# clear  清空
# 反向:删除张一和所有老师的关系
Student.objects.get(name='张一').teacher_set.clear()
# 正向:删除老张和所有学生的关系
teacher = Teacher.objects.get(name='老张')
teacher.student.clear()

# delete  删除数据
Student.objects.filter(name='王一').delete()

双下划线语法" __ "

# 取id 小于3的数据
data = User.objects.filter(id__lt=3).values('name')
# 取id 大于3 的数据
data = User.objects.filter(id__gt=3).values('name')
# 取id 大于等于3 的数据
data = User.objects.filter(id__gte=3).values('name')

# 取id 为1,2,3的数据
data = User.objects.filter(id__in=[1,2,3]).values('name')
# 取包含指定字符的数据,大小写敏感
data = User.objects.filter(name__contains='I').values('name')
# 取包含指定字符的数据,大小写不敏感
data = User.objects.filter(name__icontains='I').values('name')

# 指定字符开头的数据,大小写敏感
data = User.objects.filter(name__startswith='I').values('name')
# 指定字符开头的数据,大小写不敏感
data = User.objects.filter(name__istartswith='I').values('name')
# 指定字符结束的数据,大小写敏感
data = User.objects.filter(name__endswith='I').values('name')
# 取id 范围在(1,3)的数据,是个前闭合后闭合的范围区间
data = User.objects.filter(id__range=(1,3)).values('name')

聚合函数

  • 先导包:from django.db.models import Sum,Avg,Count,Max,Min,F,Q
# 返回值是个字典:默认key的格式(参数名_聚合函数名)
dict1 = Student.objects.all().aggregate(Count('id'), Count('name'), Avg('age'))
# print(dict1)

# 给聚合函数返回值的 key 改名字
dict2 = Student.objects.aggregate(name=Count('name'))
# print(dict2)
# 在使用聚合函数的前面加上要改的名字     新名字 = Count('name')

# F 对象,用来比较一个表中的两个字段的值的大小
data = Book.objects.filter(num__lt = F('sell_num')).all().values('name')
# print(data)

# Q 对象,处理条件查询中的and or not 关系
# and &;or |;not ~
## 查询 num 大于 10 sell_num 小于100 的书名 
book= Book.objects.filter(num__gt=10,sell_num__lt =100).all().values()
## and 
book = Book.objects.filter(Q(num__gt=10) & Q(sell_num__lt =100)).all().values("name")
# or
book = Book.objects.filter(Q(num__gt=10) | Q(sell_num__lt =100)).all().values("name")
# not
## 查找 num不大于 10 或者 sell_num 不小于 100 的书名
book = Book.objects.filter(~Q(num__gt=10) | ~Q(sell_num__lt =100)).all().values("name")
book = Book.objects.filter(~Q(num__gt=10)).all().values("name")
book = Book.objects.filter(~Q(num__gt=10) & Q(sell_num__lt =100)).all().values("name")