- 数据库增删改查
- 创建一条数据
- 创建数据方法1
- 创建数据方法2
- Django Shell
- 数据库查询
- all()方法
- 模型中定义打印方法`__str__`
- values()方法
- values_list() 方法
- order_by() 方法
- 方法的融合
- 显性查看 django 调用的 sql 语句
- 练习 查看所有书籍
- 数据过滤
- filter() 返回过滤后的值
- exclude() 返回不包含条件的值
- get() 获取符合条件的单条数据
- 查询谓词
- exact 等值匹配
- contains 包含指定值
- 更多的查询谓词
- 更新数据
- 更新单个数据 get()
- 批量更新数据 update()
- 练习 完善之前制作的图书管理
- 数据删除
- 单个数据删除
- 批量删除多个数据
- 伪删除
- 练习 给我们的页面添加删除
- F 对象和Q 对象
- F 对象
- Q对象
- 聚合查询
- 整表聚合
- 分表聚合
- 原生数据库操作
- cursor 游标
每个继承自models.Model 的模型类,都会有一个objects对象被同样继承下来
这个对象叫管理器对象数据库的增删改查可以通过模型的管理器实现
创建一条数据DjangoORM使用-种直观的方式把数据库表中的数据表示成Python对象
创建数据中每一条记录就是创建一个数据对象
创建数据方法1MyModel.object.create(属性1=值1,属性2=值2)
- 成功:返回创建好的实体对象
- 失败:抛出异常
创建 MyModel 实例对象,并调用save()进行保存
类似于类属性赋值的操作
obj = MyModel(属性1=值1,属性2=值2) obj.属性 = 值 obj.save()
只有当调用最后的 obj.save() 的时候,我们的数据才会真正的插入
Django Shell-
在Django提供了一个交互式的操作项目叫Django Shell它能够在交互模式用项目工程的代码执行相应的操作
-
利用Django Shell可以代替编写view的代码来进行直接操作
-
注意:项目代码发生变化时,重新进入Django shell
-
启动方式:
- python manage.py shell
from bookstore.models import Book # 方法一创建 b1 = Book.objects.create(书名="Python",出版社="清华大学出版社",价格=20,零售价=25) # 方法二创建 b2 = Book(书名="Django",出版社="人民大学出版社",价格=80,零售价=56.6) b2.save() # 方法二创建 bizmin = Users() bizmin.name = request.POST['name'] bizmin.age = request.POST['age'] bizmin.phone = request.POST['phone'] bizmin.save()数据库查询 all()方法
- MyModel.objects.all()
- 使用这个数据可以用来查询 MyModel 中的所有数据,等同于SELECt * FROM table
- 返回值:
- QuerySet容器对象,内部存放MyModel 实例
from bookstore.models import Book
books = Book.objects.all()
for each in books:
print("书名", each.title, "出版社:", each.pub)
模型中定义打印方法__str__
我们每一次这样都需要使用 for 循环来显示我们的内容,这个时候我们可以前往我们的模型层里面,给里面添加一个__str__方法
class Book(models.Model):
# 标题
title = models.CharField(help_text="书名",max_length=50,default='',unique=True)
# 出版社
pub = models.CharField(help_text="出版社",max_length=100,null=False,default='')
# 创建价格max_digits精度,decimal_place小数点的位数
price = models.DecimalField(help_text="价格",max_digits=7,decimal_places=2,default=0)
market_price = models.DecimalField(help_text="零售价",max_digits=7,decimal_places=2,default=0)
def __str__(self):
return f"{title} - {pub} - {price} - {market_price}"
我们没有修改数据库数据,只是修改了 Python 内的方法,不需要使用 makegrations 和migrate
values()方法- MyModel.objects.values(‘列1’, ‘列2’)
- 作用:查询部分列的数据然后返回
- 等同于 sql 中的 SELECt row1,row2 from table
- 返回值
- QuerySet ,返回的是一个QuerySet,但是内部存的是字典,每一个字典代表着一个数据,格式为:{‘row1’: ‘value1’, ‘row2’: ‘value2’}
因为这个时候我们里面是字典了,所以我们取值的时候也要使用字典的方式来取值
for each in book:
print(each['title'])
values_list() 方法
-
MyModel.objects.values_list(‘列1’, ‘列2’)
-
values_list 与 values 的区别在于 values_list 返回的是一个元组,我们最后输出元素的时候就不能使用字典的方式来取值,而是应该使用索引的方式来进行取值
- 用法 MyModel.objects.order_by(‘列1’, ‘-列2’)
- 与all()方法一致,但是它会用SQL语句的ORDER BY子句对查询结果
进行根据某个字段选择性的进行排序 - 说明
- 默认是按照升序排序,降序排序则需要在列前增加-表示
我们可以把这些方法合起来使用
- 搜索我们列名字叫 title 的元素, 然后将他们按照 价格 的降序进行排列
Book.objects.values("title").order_by("-price")
显性查看 django 调用的 sql 语句
- query方法
a = Book.objects.values("title").order_by("-price")
print(a.query)
练习 查看所有书籍
- 编写 all_book.html 模板文件
| id | title | pub | price | market_price | op |
|---|---|---|---|---|---|
| {{eachvalue}} | https://blog.csdn.net/m0_52475295/article/details/{% endfor %}更新 删除 |
我们使用模板层来让他实时更新
- 编写我们的 views.py 内的视图函数
from django.shortcuts import render
from .models import Book
def all_books(request):
# 从数据库读取数据
data = Book.objects.values().order_by('price')
dataLength = len(data)
return render(request, 'bookstore/all_book.html',locals())
- 配置主路由和子路由
# 主路由 urls.py 文件内
from django.urls import path, include
from . import views
urlpatterns = [
path('bookstore/',include('bookstore.urls'))
]
# 子路由 urls.py 文件内
from django.urls import path, re_path
from . import views
urlpatterns = [
path('all_book',views.all_books)
]
- 打开页面查看成果
可喜可贺!现在视图MTV已经完全打通,django取得阶段性胜利
数据过滤 filter() 返回过滤后的值- filter(条件)
- 语法
- MyModel.objects.filter(属性1=值1,属性2=值2)
- 作用
- 返回包含此条件的全部数据集
- 返回值
- QuerySet容器对象,内部存放 MyModel 实例
exclude() 返回不包含条件的值例子
#查询书中出版社为"清华大学出版社"的图书 from bookstore.models import Book books = Book.objects.filter(pub="清华大学出版社") for book in books: print("书名:" , book. title) #查询Author实 体中name为王老师并且age是28岁的 authors=Author.objects.filter(name='王老师' ,age=28)
- exclude(条件)
- 语法
- MyModel.objects.exclude(属性1=值1,属性2=值2)
- 作用
- 返回不包含此条件的全部数据集
- 示例:查询清华大学出版社,定价等于50以外的全部图书
books = models.Book.objects.exclude(pub="清华大学出版社" , price=50) for book in books : print(book)get() 获取符合条件的单条数据
- 语法MyModel.objects.get(条件)
- 作用
- 返回满足条件的唯一一条数据,该方法只能返回一条数据
- 查询结果多余一条数据则抛出Model.MultipleObjectsReturned异常
- 如果没有数据则抛出Model.DoesNotExist异常
我们的 django 没有办法直接书写类似 id>5这样的条件,但是我们可以使用查询谓词来达到同样的效果
- 定义
- 做更灵活的条件查询时需要使用查询谓词
- 说明
- 每一个查询谓词是一个独立的查询功能
Author.objects.filter(id__exact=1) # 等同于 SELECt * from author where id =1
这里我们 __exact前面的id,表示我们想要查询的属性,后面是我们的值
我们的 exact 主要用来查询 null 值
contains 包含指定值Author.objects.filter(name__contains="w") # 等同于 SELECt * FROM author WHERe name like '%w'更多的查询谓词
| 查询谓词 | 说明 |
|---|---|
| __startswith | 查询以 XXX 开始 |
| __endswith | 查询以 XXX 结束 |
| __gt | 大于指定值( > gt >) |
| __gte | 大于等于( ≥ geq ≥) |
| __lt | 小于( < lt < ) |
| __lte | 小于等于( ≤ leq ≤) |
| __in | 查询数据是否在指定范围内 |
| __range | 查询数据是否在指定的区间范围内 |
Author.objects.filter(country_in=['中国','日本','韩国'])
#等同于select * from author where country in ('中国','日本','韩国')
# 查询年龄在指定区间的所有作者 Author.objects.filter(age__range=(35,50)) # 等同于 SELECt * FROM author WHERe age BETWEEN 35 and 50;更新数据 更新单个数据 get()
- 查
- 通过 get() 得到需要修改的实体对象
- 改
- 通过 对象.属性 的方法修改数据
- 保存
- 通过 对象.save() 保存数据
from bookstore.models import Book # 获取一条数据,id得是为1 a = Book.objects.get(id=1) # 修改这个数据的价格 a.price = 50 # 保存数据 a.save()
- 没有更新之前的数据
- 更新之后的数据
可以看到我们的 price 变成了 50
批量更新数据 update()-
使用方法
- update(属性 = 值) 来对选中的值进行批量更改
-
例子1 将 id 大于 3 的所有图书价格定义为 100 元
# 将 id 大于 3 的所有图书价格定义为 100 元 from bookstore.models import Book # 选中所有大于3的数据 books = Book.objects.filter(id__gt=3) # 批量进行更新 books.update(price = 100)
- 例子2 把所有的图书零售价都设置为 80
# 把所有的图书零售价都设置为 80 from bookstore.models import Book # 选中所有大于3的数据 books = Book.objects.all() # 进行批量修改 books.update(market_price = 80)练习 完善之前制作的图书管理
- 制作页面为 all_book.html 页面的更新链接添加真正的逻辑
| id | title | pub | price | market_price | op |
|---|---|---|---|---|---|
| {{eachvalue}} | https://blog.csdn.net/m0_52475295/article/details/{% endfor %}更新 删除 |
- 前往视图设置函数
# views.py 文件内
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from .models import Book
def update_book(request,id):
try:
book = Book.objects.get(id=id)
except:
print("未找到相关图书")
return HttpResponse("未找到相关图书")
if request.method == 'GET':
return render(request, 'bookstore/update_book.html',locals())
if request.method == 'POST':
# 读取
#title = request.POST.get('title','ERROR')
#pub = request.POST.get('pub','ERROR')
price = request.POST.get('price','ERROR')
market_price = request.POST.get('market_price','ERROR')
# 修改
#book.title = title
#book.pub = pub
book.price = price
book.market_price = market_price
# 保存
book.save()
return HttpResponseRedirect('/bookstore/all_book')
- 设置路由,顺便添加反向解析
# 子路由 urls.py 文件内
from django.urls import path, re_path
from . import views
# 添加反向代理 name
urlpatterns = [
path('all_book',views.all_books,name='all_book'),
path('update_book/',views.update_book,name='update_book'),
]
- 制作被更新后的操作界面
Document


