0
点赞
收藏
分享

微信扫一扫

Django ORM 数据库常用操作

设置数据库字段映射:

from django.db import models
import sqlite3

class User(models.Model):
id = models.AutoField(primary_key=True) # 设置ID字段(默认自增长)
username = models.CharField(max_length=32) # 设置用户名最大32个字符
password = models.CharField(max_length=32) # 设置用户密码
data = models.DateField() # 注册日期
# 设置最大5位数,其中小数点占用2位
number = models.DecimalField(max_digits=5,decimal_places=2)

更新与迁移数据库:

python manage.py makemigrations   # 将你的数据库变动记录下来(并不会帮你创建表)
python manage.py migrate # 将你的数据库变动正在同步到数据库中
python manage.py createsuperuser # 创建一个超级用户

ORM 数据添加与删除:

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
# ---------------------------------------------------------------------
# 添加表记录,方式1
models.User.objects.create(username="admin",password="123123",data="2019-01-01",number=3.1)
models.User.objects.create(username="guest", password="123456", data="2019-02-12", number=2.1)
models.User.objects.create(username="admin", password="123123", data="2019-02-12", number=2.1)
models.User.objects.create(username="wangwu", password="rwqwe33", data="2018-02-12", number=4.1)
models.User.objects.create(username="zhangsan", password="8888", data="2017-05-21", number=9.9)
models.User.objects.create(username="lisi", password="99994", data="2010-2-11", number=8.1)

# 添加表记录,方式2
dic = {"username":"wangermazi","password":"123321","data":"2019-12-12","number":2.15}
models.User.objects.create(**dic)

# 添加表记录,方式3
obj = models.User(username="lyshark",password="1233",data="2010-01-01",number=3.14)
obj.save()

# 添加表记录,方式4
obj = models.User()
obj.username="django"
obj.password="55555"
obj.data="2003-01-12"
obj.number="3.14"
obj.save()

# ---------------------------------------------------------------------
# 更新数据的方式
models.User.objects.filter(id=2).update(username="hello")
# 第二种更新数据的方式
obj = models.User.objects.get(id=2)
obj.username="tomcat"
obj.password="tomcat"
obj.save()

# ---------------------------------------------------------------------
# 删除数据的方式
models.User.objects.filter(id=1).delete() # 删除id是1的一条数据
models.User.objects.get(id=2).delete() # 删除id是2的一条数据
models.User.objects.all().delete() # 删除所有数据

return HttpResponse("<h1>hello lyshark</h1>")

ORM 单表查询操作:

from django.shortcuts import render,HttpResponse
from MyWeb import models

def select(request):
# 通过ORM模型执行原生SQL语句
ret = models.CPU.objects.raw('select * from MyWeb_cpu where Times>="{}" and Times <="{}";'.
format("2020-01-02T09:29","2020-01-02T09:30"))
for item in ret: # 遍历出内部数据
print(item.Times)
print(item.__dict__)

print(models.User.objects.all()) # 获取所有数据
print(models.User.objects.count()) # 获取数据库中的总共记录数
print(models.User.objects.filter(username="admin").count()) # 获取admin这条记录的数量

print(models.User.objects.filter(username="lyshark")) # 查询username=lyshark的记录
print(models.User.objects.filter(id=1,username="admin")) # 查询ID=1且username=admin的记录

# 查询用户名是lyshark,并且拿到它的id与password字段数据
print(models.User.objects.filter(username="lyshark").values("id","password"))
# 查询记录中是lyshark的记录,并且拿到它的id和password,且转换成元组的形式返回
print(models.User.objects.filter(username="lyshark").values_list("id","password"))

print(models.User.objects.get(username="lyshark")) # 得到model对象
print(models.User.objects.exclude(username="admin")) # 查询所有用户记录,排除掉admin的记录
print(models.User.objects.filter(username="admin").exclude(id=3)) # 支持链式过滤,查找admin的记录,排除掉id=3

print(models.User.objects.all().order_by("id")) # 查询记录并以id字段正向排序
print(models.User.objects.all().order_by("-id")) # 同样可以实现反向排序
print(models.User.objects.all().order_by("id").reverse()) # 查询记录并以id字段反向排序
print(models.User.objects.filter(username="admin").values("username").distinct()) # 去重

print(models.User.objects.all().first()) # 查询第一条记录
print(models.User.objects.all().last()) # 查询最后一条记录

print(models.User.objects.filter(id__lt=5,id__gt=1)) # 查询ID小于5且大于1的数据
print(models.User.objects.filter(id__in=[1,2,3])) # 查询ID等于1,2,3的行
print(models.User.objects.filter(id__range=[1,100])) # 查询UD在1-100范围内的行

print(models.User.objects.filter(username__contains="ad").values_list()) # 模糊查询(大小写敏感)
print(models.User.objects.filter(username__icontains="ad").values_list()) # 模糊查询(大小写不敏感)

print(models.User.objects.all()[1:3]) # 查询后切片,只取出1-3行元素
print(models.User.objects.all()[2:9]) # 查询切片,只取出2-9行元素

return HttpResponse("<h1>hello lyshark</h1>")

ORM 一对多的使用:: 比如说一个出版社可以出版多本书,但是一本书只能够在一个出版社进行发表,这就是一个典型的一对多的关系,一对多​​models.ForeignKey()​​,如下我们首先创建一个Book表,然后创建一个Publish表,一个Publish记录中可以包含多本书.

from django.db import models
import sqlite3

class Book(models.Model):
id = models.AutoField(primary_key=True) # 自增长的一个主键
title = models.CharField(max_length=32) # 书籍名称
data = models.DateField() # 出版日期
price = models.DecimalField(max_digits=5,decimal_places=2) # 一共5位保留两位小数
# 建立一对多关系,关联到Publish表中,django会自动在publish_key后面加上_id
publish_key = models.ForeignKey("Publish",on_delete=models.CASCADE)

class Publish(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) # 出版社名字
addr = models.CharField(max_length=32) # 出版社地址
python manage.py makemigrations   # 将你的数据库变动记录下来(并不会帮你创建表)
python manage.py migrate # 将你的数据库变动正在同步到数据库中

创建一对多关系

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
# 首先创建两个出版社名字
models.Publish.objects.create(name="人民出版社",addr="中国 北京")
models.Publish.objects.create(name="清华出版社",addr="北京 海淀")

# 一对多关系的添加方式:第一种方式
models.Book.objects.create(title="<Python从入门到入土>",data="2019-12-12",price=22,publish_key_id=1)
models.Book.objects.create(title="<java 从入门到放弃>", data="2019-11-24", price=55, publish_key_id=1)
models.Book.objects.create(title="<go 从闰土到入土>", data="2018-11-24", price=77, publish_key_id=1)

# 一对多关系的添加方式:第二种添加方式(推荐)
obj = models.Publish.objects.filter(name="清华出版社")[0]
print("出版社ID号:{}".format(obj.id))
models.Book.objects.create(title="<简爱>",data="2019-01-01",price=45.5,publish_key_id=obj.id)
models.Book.objects.create(title="<骆驼祥子>", data="2007-05-01", price=25.5, publish_key_id=obj.id)

# 一对多关系的添加方式:第三种添加方式
obj = models.Publish.objects.get(name="人民出版社")
book = models.Book(title="<django 姜哥>",data="2014-01-02",price=22.6,publish_key_id=obj.id)
book.save()

return HttpResponse("<h1>hello lyshark</h1>")

一对多的查询

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
# 普通查询:查询人民出版社出版过的所有书籍
obj = models.Publish.objects.get(name="人民出版社")
bookOBJ = obj.book_set.all()
for item in bookOBJ:
print("出版书籍:{} 出版日期:{} ".format(item.title,item.data))

# 正向查询:查询<Python从入门到入土>这本书的出版社的地址
bookOBJ = models.Book.objects.filter(title="<Python从入门到入土>")[0]
print("书籍:{} 出版地址是:{}".format(bookOBJ.title,bookOBJ.publish_key.addr))

# 反向查询: 查询人民出版社出版过的所有的书的价格和名字
publishOBJ = models.Publish.objects.filter(name="人民出版社")[0]
book_dic = publishOBJ.book_set.all().values('title','price')[0]
print("书籍:{} 当前价格:{}".format(book_dic['title'],book_dic['price']))

# 另一种查询:查询人民出版社出版过的所有书籍,并打印出价格 (高效查询)
ret = models.Publish.objects.filter(name="人民出版社").values("book__title","book__price")
for i in range(0,len(ret)):
print("出版书籍: {} 当前价格:{} ".format(ret[i]['book__title'],ret[i]['book__price']))

# 第二种查询方式(该方法更简单)
ret = models.Publish.objects.filter(name="人民出版社").values("book__title","book__price")
for i in ret:
print("出版书籍: {} 当前价格:{} ".format(i['book__title'], i['book__price']))

return HttpResponse("<h1>hello lyshark</h1>")

ORM 多对多的使用:: 一个作者可以写多本书,同样的一本书可能是由多个作者一起写出来的,这就是多对多的关系,多对多​​models.ManyToManyField()​

from django.db import models
import sqlite3

class Book(models.Model):
id = models.AutoField(primary_key=True) # 自增长的一个主键
title = models.CharField(max_length=32) # 书籍名称
data = models.DateField() # 出版日期
price = models.DecimalField(max_digits=5,decimal_places=2) # 一共5位保留两位小数
# 建立一对多关系,关联到Publish表中,django会自动在publish_key后面加上_id
publish_key = models.ForeignKey("Publish",on_delete=models.CASCADE)

# 多对多,django会自动创建一个新的表book_author用来记录多对多键值对
author = models.ManyToManyField("Author")

class Publish(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) # 出版社名字
addr = models.CharField(max_length=32) # 出版社地址

class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32) # 作者姓名
age = models.IntegerField() # 作者年龄

多对多的数据创建操作技巧

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
# 我们来创建几个书籍作者
models.Author.objects.create(name="张三", age=22)
models.Author.objects.create(name="李四", age=33)
models.Author.objects.create(name="王五", age=67)
models.Author.objects.create(name="老王", age=87)
models.Author.objects.create(name="小张", age=43)

# -----------------------------------------------------------------------------
# 拿到一个出版社的对象,我们这本《鲁迅散文》是清华出版社的
PublishOBJ = models.Publish.objects.filter(name="清华出版社")[0]
# 接着我们创建一本书,并关联一对多的关系(清华出版社->鲁迅散文)
BookObj = models.Book.objects.create(title="<鲁迅散文>",data="2019-01-23",price=34.5,publish_key=PublishOBJ)
# 接着我们取出本书的作者:比如本书是由张三,李四,老王写出来的.
zhangsan = models.Author.objects.filter(name="张三")[0]
lisi = models.Author.objects.filter(name="李四")[0]
laowang = models.Author.objects.filter(name="老王")[0]
# 最后我们将这本<鲁迅散文>与这三个作者关联起来
BookObj.author.add(zhangsan,lisi,laowang)

多对多的查询

from django.shortcuts import render,HttpResponse
from MyWeb import models

def insert(request):
# 正向查询:查询<鲁迅散文>这本书是由那几个人写的,并打印出他的年龄
BookOBJ = models.Book.objects.filter(title="<鲁迅散文>")[0]
name = BookOBJ.author.all().values("name")
age = BookOBJ.author.all().values("age")
for i in range(0,len(name)):
print("书籍作者: {}".format(name[i]['name']))

# 反向查询:查询李四这个作者写过那几本书
lisi = models.Author.objects.filter(name="李四")[0]
print("该作者写过: "+ lisi.book_set.all().first().title)

# 查询人民出版社出版过的所有书籍
publish = models.Publish.objects.get(name="人民出版社")
booklist = publish.book_set.all()
for i in range(0,len(booklist)):
print("查询到人民出版社,出版过: {}".format(booklist[i].title))

# 另外一种查询方式:查询张三这个人写过的书
ret = models.Author.objects.filter(name="张三").values("book__title")
print(ret)

return HttpResponse("hello lyshark")

ORM 聚合查询与分组查询:

from django.db.models import Avg,Sum,Count,Max,Min

def insert(request):
# 查询所有图书的平均价格
print(models.Book.objects.all().aggregate(Avg("price")))
# 另一种自定义命名查询
print(models.Book.objects.all().aggregate(avg = Avg("price")))
# 如果你希望生成不止一个聚合,可以这样写
print(models.Book.objects.all().aggregate(avg=Avg("price"),max=Max("price"),min=Min("price")))

# 查询出,每本书的作者的总个数
#print(models.Book.objects.all().annotate(num=Count("author__name")).values("num"))
bookOBJ = models.Book.objects.all().annotate(num=Count("author__name"))
for item in bookOBJ:
print("书籍:{} 作者数量:{}".format(item.title,item.num))

# 统计出每个出版社出版过最便宜的书的价格(方式1)
print(models.Publish.objects.all().annotate(MinBook=Min("book__price")).values("name","MinBook"))

# 统计出每个出版社出版过最贵的书的价格(方式2)
publishOBJ = models.Publish.objects.annotate(MaxBook=Max("book__price"))
for item in publishOBJ:
print("出版社:{} 最贵的书:{}".format(item.name,item.MaxBook))

# 统计出书籍名称以<鲁迅开头的书籍,是由几个作者写的
print(models.Book.objects.filter(title__startswith="<鲁迅").annotate(Num=Count("author__name")).values("Num"))
bookOBJ = models.Book.objects.filter(title__startswith="<鲁迅").annotate(Num=Count("author__name"))
for item in bookOBJ:
print("书籍:{} 由{}个作者共同完成".format(item.title,item.Num))

# 统计不止两个作者的图书,并打印出图书的名字
print(models.Book.objects.annotate(num=Count("author__name")).filter(num__gt=2).values("title","num"))

# 根据一本图书作者数量的多少对查询集QuerySet进行排序
print(models.Book.objects.all().annotate(num=Count("author__name")).order_by("num"))

# 查询每个作者出过的书的总价格,每个作者出过书之和
print(models.Author.objects.all().annotate(PriceSum=Sum("book__price")).values("name","PriceSum"))

return HttpResponse("hello lyshark")

ORM Django之F查询与Q查询:

from django.db.models import F,Q

def select(request):
# ---------------------------------------------------------------
# F查询:专门针对对象中某列中的某个值进行操作

# 需求:通过F查询我们将book表中所有图书的价格全部涨价20元
# F查询:作用是取出 price 字段的值,然后进行 +20 的操作
models.Book.objects.all().update(price=F("price") + 20)
# 查询评论数大于收藏数2倍的书籍
models.Book.objects.filter(commnetNum__lt=F('keepNum') * 2)
# 查看评论数大于阅读数的书
print(models.Book.objects.filter(commentNum__gt=F("readNum")))

# ---------------------------------------------------------------
# Q查询: 用于应对更加复杂的查询需求,例如使用and或or进行的复杂查询.

# Q查询(单条件查询): 查询book表中,id=1的书,并打印出它的title字段.
print(models.Book.objects.filter(Q(id=1)).values("title"))
# Q查询(多条件查询):查询book表中,id=1并且title=<Python从入门到入土> 查到后打印出price价格.
print(models.Book.objects.filter(Q(id=1) & Q(title="<Python从入门到入土>")).values("price"))

# Q查询(跨表查询):查询author__name=张三的人写过的书,并打印出title
print(models.Book.objects.filter(Q(author__name="张三")).values("title"))

版权声明:本博客文章与代码均为学习时整理的笔记,文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!





举报

相关推荐

0 条评论