每个继承自 models.Model 的模型类,都会有一个 objects 对象被同样继承下来。这个对象叫管理器对象
数据库的增删改查可以通过模型的管理器实现
class MyModel(models.Model):
...
MyModel.objects.create(...) # objects 是管理器对象
Django 使用一种直观的方式把数据库表中的数据表示成Python 对象
创建数据中每一条记录就是创建一个数据对象
MyModel.objects.create(属性1=值1, 属性2=值1,…)
创建 MyModel 实例对象,并调用 save() 进行保存
obj = MyModel(属性=值,属性=值)
obj.属性=值
obj.save()
在Django提供了一个交互式的操作项目叫 Django Shell
它能够在交互模式用项目工程的代码执行相应的操作
利用 Django Shell 可以代替编写View的代码来进行直接操作
在Django Shell 下只能进行简单的操作,不能运行远程调式
启动方式:
$ python3 manage.py shell
然后用 Django Shell 添加如下数据
图书信息
书名 | 定价 | 零售价 | 出版社 |
---|---|---|---|
Python | 20.00 | 25.00 | 清华大学出版社 |
Django | 70.00 | 75.00 | 清华大学出版社 |
JQuery | 90.00 | 85.00 | 机械工业出版社 |
Linux | 80.00 | 65.00 | 机械工业出版社 |
HTML5 | 90.00 | 105.00 | 清华大学出版社 |
作者信息:
姓名 | 年龄 | 邮箱 |
---|---|---|
小明 | 20 | [email protected] |
小王 | 17 | [email protected] |
小红 | 12 | [email protected] |
数据库的查询需要使用管理器对象进行
通过 MyModel.objects 管理器方法调用查询接口
方法 | 说明 |
---|---|
all() | 查询全部记录,返回QuerySet查询对象 |
get() | 查询符合条件的单一记录 |
filter() | 查询符合条件的多条记录 |
exclude() | 查询符合条件之外的全部记录 |
… |
all()方法
方法: all()
用法: MyModel.objects.all()
作用: 查询MyModel实体中所有的数据
返回值: QuerySet容器对象,内部存放 MyModel 实例
示例:
from bookstore.models import Book
books = Book.objects.all()
for book in books:
print("书名", book.title, '出版社:', book.pub)
在模型类中定义 def __str__(self):
方法可以自定义默认的字符串
class Book(models.Model):
title = ...
def __str__(self):
return "书名: %s, 出版社: %s, 定价: %s" % (self.title, self.pub, self.price)
查询返回指定列(字典表示)
方法: values(‘列1’, ‘列2’)
用法: MyModel.objects.values(…)
作用: 查询部分列的数据并返回
返回值: QuerySet
示例:
from bookstore.models import Book
books = Book.objects.values("title", "pub")
for book in books:
print("书名", book["title"], '出版社:', book['pub'])
print("book=", book)
查询返回指定列(元组表示)
方法:values_list(‘列1’,‘列2’)
用法:MyModel.objects.values_list(…)
作用:
返回值: QuerySet容器对象,内部存放 元组
示例:
from bookstore.models import Book
books = Book.objects.values_list("title", "pub")
for book in books:
print("书名", book[0], '出版社:', book[1])
print("book=", book) # ('Python', '清华大学出版社')...
排序查询
方法:order_by
用法:MyModel.objects.order_by(‘-列’,‘列’)
作用:
说明:
默认是按照升序排序,降序排序则需要在列前增加’-'表示
示例:
from bookstore.models import Book
books = Book.objects.order_by("price")
for book in books:
print("书名:", book.title, '定价:', book.price)
条件查询 - filter
方法: filter(条件)
语法:
MyModel.objects.filter(属性1=值1, 属性2=值2)
返回值:
说明:
Books.objects.filter(price=20, pub="清华大学出版社")
返回定价为20 且
出版社为"清华大学出版社"的全部图书示例:
# 查询书中出版社为"清华大学出版社"的图书
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
方法: exclude(条件)
语法:
作用:
条件
的 全部的数据集示例:
清华大学出版社,定价等于50
以外的全部图书books = Book.objects.exclude(pub="清华大学出版社", price=50)
for book in books:
print(book)
条件查询 - get
方法: get(条件)
语法:
作用:
说明:
示例:
from bookstore.models import Book
book = Book.objects.get(id=1)
print(book.title)
__exact
: 等值匹配
Author.objects.filter(id__exact=1)
# 等同于select * from author where id = 1
__contains
: 包含指定值
Author.objects.filter(name__contains='w')
# 等同于 select * from author where name like '%w%'
__startswith
: 以 XXX 开始
__endswith
: 以 XXX 结束
__gt
: 大于指定值
Author.objects.filer(age__gt=50)
# 等同于 select * from author where age > 50
__gte
: 大于等于
__lt
: 小于
__lte
: 小于等于
__in
: 查找数据是否在指定范围内
Author.objects.filter(country__in=['中国','日本','韩国'])
# 等同于 select * from author where country in ('中国','日本','韩国')
__range
: 查找数据是否在指定的区间范围内
# 查找年龄在某一区间内的所有作者
Author.objects.filter(age__range=(35,50))
# 等同于 SELECT ... WHERE Author BETWEEN 35 and 50;
详细内容参见: https://docs.djangoproject.com/en/2.2/ref/models/querysets/#field-lookups
示例
MyModel.objects.filter(id__gt=4)
# 等同于 SELECT ... WHERE id > 4;
修改单个实体的某些字段值的步骤:
如:
from bookstore.models import Book
abook = Book.objects.get(id=10)
abook.market_price = "10.5"
abook.save()
通过 QuerySet 批量修改 对应的全部字段
直接调用QuerySet的update(属性=值) 实现批量修改
返回值:更新数据的数量
如:
# 将id大于3的所有图书价格定为0元
books = Book.objects.filter(id__gt=3)
books.update(price=0)
# 将所有书的零售价定为100元
books = Book.objects.all()
books.update(market_price=100)
删除单个对象
步骤
示例:
try:
auth = Author.objects.get(id=1)
auth.delete()
except:
print(删除失败)
删除查询结果集
步骤
示例:
# 删除全部作者中,年龄大于65的全部信息
auths = Author.objects.filter(age__gt=65)
auths.delete()
不带分组聚合
不带分组的聚合查询是指导将全部数据进行集中统计查询
聚合函数【需要导入】:
from django.db.models import *
语法:
返回结果:
示例:
# 得到所有书的平均价格
from bookstore.models import Book
from django.db.models import Avg
result = Book.objects.aggregate(myAvg=Avg('price'))
print("平均价格是:", result['myAvg'])
print("result=", result) # {"myAvg": 58.2}
# 得到数据表里有多少本书
from django.db.models import Count
result = Book.objects.aggregate(mycnt=Count('title'))
print("数据记录总个数是:", result['mycnt'])
print("result=", result) # {"mycnt": 10}
分组聚合
分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。
语法:
用法步骤:
通过先用查询结果MyModel.objects.values 查找查询要分组聚合的列
MyModel.objects.values(‘列1’, ‘列2’)
如:
pub_set = Book.objects.values('pub')
print(pub_set) #
通过返回结果的 QuerySet.annotate 方法分组聚合得到分组结果
QuerySet.annotate(名=聚合函数(‘列’))
返回 QuerySet 结果集,内部存储结果的字典
如:
pub_count_set = pub_set.annotate(myCount=Count('pub'))
print(pub_count_set) #
示例:
def test_annotate(request):
from django.db.models import Count
from . import models
# 得到所有出版社的查询集合QuerySet
pub_set = models.Book.objects.values('pub')
# 根据出版社查询分组,出版社和Count的分组聚合查询集合
pub_count_set = pub_set.annotate(myCount=Count('pub')) # 返回查询集合
for item in pub_count_set:
print("出版社:", item['pub'], "图书有:", item['myCount'])
return HttpResponse('请查看服务器端控制台获取结果')
作用:
用法
from django.db.models import F
语法:
from django.db.models import F
F('列名')
说明:
示例1
Book.objects.all().update(market_price=F('market_price')+10)
'UPDATE `bookstore_book` SET `market_price` = (`bookstore_book`.`market_price` + 10)
# 以上做法好于如下代码
books = Book.objects.all()
for book in books:
book.market_price=book.marget_price+10
book.save()
示例2
from django.db.models import F
from bookstore.models import Book
books = Book.objects.filter(market_price__gt=F('price'))
'SELECT * FROM `bookstore_book` WHERE `bookstore_book`.`market_price` > (`bookstore_book`.`price`)
for book in books:
print(book.title, '定价:', book.price, '现价:', book.market_price)
当在获取查询结果集 使用复杂的逻辑或 |
、 逻辑非 ~
等操作时可以借助于 Q对象进行操作
如: 想找出定价低于20元 或 清华大学出版社的全部书,可以写成
Book.objects.filter(Q(price__lt=20)|Q(pub="清华大学出版社"))
Q对象在 数据包 django.db.models 中。需要先导入再使用
from django.db.models import Q
作用
运算符:
语法
from django.db.models import Q
Q(条件1)|Q(条件2) # 条件1成立或条件2成立
Q(条件1)&Q(条件2) # 条件1和条件2同时成立
Q(条件1)&~Q(条件2) # 条件1成立且条件2不成立
...
示例
from django.db.models import Q
# 查找清华大学出版社的书或价格低于50的书
Book.objects.filter(Q(market_price__lt=50) | Q(pub_house='清华大学出版社'))
# 查找不是机械工业出版社的书且价格低于50的书
Book.objects.filter(Q(market_price__lt=50) & ~Q(pub_house='机械工业出版社'))
使用MyModel.objects.raw()进行 数据库查询操作查询
语法:
MyModel.objects.raw(sql语句,[拼接参数])
用法
MyModel.objects.raw('sql语句', [拼接参数])
返回值:
示例
books = Book.objects.raw('select * from bookstore_book')
for book in books:
print(book)
#sql注入问题
s1 = Book.objects.raw('select * from bookstore_book where id=%s'%('1 or 1=1'))
s2 = Book.objects.raw('select * from bookstore_book where id=%s',['1 or 1=1'])
使用django中的游标cursor对数据库进行 增删改查 操作
在Django中跨国模型类直接操作数据库
使用步骤:
导入cursor所在的包
from django.db import connection
用创建cursor类的构造函数创建cursor对象,再使用cursor对象,为保证在出现异常时能释放cursor资源,通常使用with语句进行创建操作
如:
from django.db import connection
with connection.cursor() as cur:
cur.execute('执行SQL语句', '拼接参数')
示例
# 用SQL语句将id 为 10的 书的出版社改为 "XXX出版社"
from django.db import connection
with connection.cursor() as cur:
cur.execute('update bookstore_book set pub_house="XXX出版社" where id=10;')
with connection.cursor() as cur:
# 删除 id为1的一条记录
cur.execute('delete from bookstore_book where id=10;')