Django通过模型迁移除数据库的数据表,又提供了操作数据模型的API来实现对目标数据库的读写操作。数据库的读写操作主要对数据进行增、删、 改、查。
Django带有shell模式(启动命令行和执行脚本),该模式主要为方便开发人员开发和调试程序。
在manage.py所在目录下执行以下命令即可进入shell模式:
python manage.py shell
导入相应的应用模型文件,就可以对模型数据进行操作 (这里以应用index为参考)。
from index.models import *
这里以Product模型为例子,显示对其进行数据操作的步骤:
- 从 models.py 中导入模型 Product。
- 对模型 Product 声明并实例化,生成对象 p。
- 对象 p 的属性进行逐一赋值,对象 p 的属性来自于模型 Product 所定义的字段。完成赋值后需要对 p 进行保存才能作用在目标数据库。
现在对一下俩个表进行shell操作:
下面是三种插入操作:
# 第一种
>>> p = Product()
>>> p . name = '荣耀 V9'
>>> p .weight = ' lllg'
>>> p . size = ' 120*75女 7mm '
>>> p . type_id = 1
>>> p . save ()
# 第二种
#通过 Django 的 ORM 框架提供的 API 实现,使用 create 方法实现数据插入
>>> Product.objects.create(name='荣耀 V9',weight='lllg', size='120*75*7mm',type_id=l)
# 第三种
>>> p = Product(name='荣耀 V9',weight='lllg',size='120*75mm' ,type_id=l)
>>> p.save()
更新操作:
更新的实现步骤与数据插入的方法大致相同,唯一的区别是在模型实例化之后,要更新数据,需要先进行一次数据查询,将查询结果以对象的形式赋给 p,最后对 p 的属性重新赋值就能实现数据的更新。
>>> p = Product.objects.get(id=9)
>>> p.name = '华为荣耀 V9'
>>> p.save()
还可以使用update方法实现单条或多条数据的更新。
#通过 Django 的 ORM 框架提供的 API 实现
#更新单条数据,查询条件 get 适用于查询单条数据
Product.objects.get(id=9).update(name='华为荣耀 V9')
#更新多条数据,查询条件 filter 以列表格式返回,查询结果可能是一条或多条数据
Product.objects.filter(name='荣耀 V9').update(name='华为荣耀 V9')
#全表数据更新,不使用查询条件, 默认对全表的数据进行更新
Product.objects.update(name='华为荣耀 V9')
删除操作:
如果要对数据进行删除处理,有三种方式: 删除表中全部数据、删除一条数据和删除多条数据。
#删除表中全部数据
Product.objects.all().delete()
#删除一条 id 为 1 的数据
Product.objects.get(id=l).delete()
#删除多条数据
Product.objects.filter(name= '华为荣耀 V9').delete ()
从上面的操作可以看出都用到了查询操作get和filter, 查询条件get和filter的区别:
- 查询条件 get: 查询字段必须是主键或者唯一约束的字段,并且查询的数据必 须存在,如果查询的字段有重复值或者查询的数据不存在,程序都会抛出异 常信息。
- 查询条件 filter: 查询字段没有限制,只要该字段是数据表的某一字段即可。 查询结果以多表的形式返回,如果查询结果为空 (查询的数据在数据库中找不到) ,就返回空列表。
查询操作:
操作说明 | 代码示例 |
全表查询, 等同于 SQL 语句 Select * from index_product,数据以列表形式返回 | >>> p = Product.objects.all() >>> p[1].name ' HUAWEI nova 2s ' |
查询前 5 条数据, 等同于 SQL 语句 Select * from index_product LIMIT 5 SQL 语句里面的 LIMIT 方法, 在 Django 中使用 Python 的列表截取分解即可实现 | >>> p = Product.objects.all()[:5] |
查询某个字段, 等同于 SQL 语句 Select name from index product values 方法,以列表形式返回数据, 列表元素以字典格式表示 | >>> p = Product.objects.values('name') >>> p[1] ['name'] ' HUAWEI nova 2s ' |
values list 方法,以列表表示返回数据,列表元素以元组格式表示 | >>> p = Product.objects.values_list('name')[:3] >>> p <QuerySet [('荣耀 V10' ,),('HUAWEI nova 2s',),('荣耀 Waterplay')]> |
使用 get 方法查询数据,等于同 SQL 语句 Select * from index product where id=2 | >>> p = Product.objects.get(id = 2) >>> p.name ' HUAWEI nova 2s ' |
SQL 的 and 查询主要在 filter 里面添加多个查询条件 | >>> p = Product.objects.filter(name=' 华为荣耀 V9 ',id=9) >>> p <QuerySet [<Product : Product object (9)>]> |
使用 count 方法统计查询数据的数据量 | >>> p = Product.objects.filter(name= ' 华为荣耀 V9 ' ).count() >>> p 2 |
SQL 的 or 查询,需要引入 Q,编写格式: Q(field=value) IQ(field=value) 等同于 SQL 语句 Select * from index product where name= ' 华为荣耀 V9 ' or id=9 | >>> from django.db.models import Q >>> p = Product.objects.filter(Q(name= '华为荣耀 V9') | IQ(id=9)) |
去重查询, distinct 方法无须设置参数,去重方式根据 values 设置的字段执行 等同 SQL 语句 Select DISTINCT name from index_product where name = ' 华为荣耀 V9 ' | >>> p = Product.objects.values( ' name ' ).filter(name= ' 华为荣耀V9 ' ).distinct () >>> p <QuerySet [{ ' name 川 ' 华为荣耀 V9 ' } ] > |
根据字段 id 降序排列, 降序只要在 order by 里面的字段前面加 "-" 即可 # order_by 可设置多字段排列,如 Product.objects.order_by( '-id’ , name ') | >>> p = Product.objects.order_by( ' -id' ) >>> p |
聚合查询, 实现对数据值求和、求平均值等。 Django 提供 annotate 和 aggregate 方法实现 annotate 类似于 SQL 里面的 GROUP BY 方法, 如果不设置 values,就会默认对主键进行 GROUP BY 分组 等同于 SQL 语句 Select name, SUM(id) AS ' id sum' from index product GROUP BY name ORDER BY NULL | >>> from django.db.models import Sum, Count >>> p = Product.objects.values(' name ') .annotate(Sum( ' id' )) >>> print(p.query) |
aggregate 是将某个字段的值进行计算并只返回计算结果 等同于 SQL 语句 Select COUNT(id) AS ' id count ' from index_product | >>> from django.db .models import Count >>> p = Product.objects.aggregate (id_count=Count ( 'id')) >>> p {' id count ' : 11} |
查询条件 filter 和 get 使用等值的方法来 匹配结果。 若想使用大于、不等于和模糊查询的匹配方法,则可以使用下表:
匹配符 | 使用 | 说明 |
__exact | filter(name__exact= ' 荣耀') | 精确等于,如SQL的like '荣耀' |
__iexact | filter(name__iexact= ' 荣耀') | 精确等于并忽略大小写 |
__contams | filter(name__contains= '荣耀') | 模糊匹配, 如SQL的like('%荣耀%' ) |
__icontalns | filter(name__icontains='荣耀') | 模糊匹配,忽略大小写 |
__gt | filter(id__gt=5) | 大于 |
__gte | filter( id__gte=5) | 大于等于 |
__lt | filter(id__lt=5) | 小于 |
__lte | filter(id__lte=5) | 小于等于 |
__in | filter(id__in=[1,2,3]) | 判断是否在列表内内 |
__startswith | filter(name__startswith='荣耀') | 以...开头 |
__endswith | filter(name __endswith=' 荣耀') | 以...结尾 |
__istartswith | filter(name__istartswith= '荣耀') | 以...开头并忽略大小写 |
__iendswith | filter(name__iendswith= '荣耀') | 以...结尾并忽略大小写 |
__range | filter(name__range='荣耀') | 在....范围内 |
__year | filter(date__year=2018) | 日期字段的年份 |
__month | filter(date__month=12) | 日期字段的月份 |
__day | filter( dat__day=30) | 日期字段的天数 |
__isnull | filter(name__isnull=TruelFalse) | 判断是否为空 |
多表查询:
一对多或一对一的表关系是通过外键实现关联的,而多表查询分为正向查询和 反向查询。以模型 Product 和 Type 为例:
- 如果查询对象的主体是模型 Type,要查询模型 Type 的数据,那么该查询称 为正向查询。
- 如果查询对象的主体是模型 Type,要通过模型 Type 查询模型 Product 的数据, 那么该查询称为反向查询。
>>> t = Type.objects.filter(product_id=ll )
#正向查询
>>> t <QuerySet [<Type: Type object (1)>]>
>>> t[0].type_name
' 手机 '
#反向查询
>>> t[0].product_set.values('name')
<QuerySet [{ ' name 勺 ' 荣耀 V工0 ' } , {' name 气 ' HUAWE工 nova 2s ' }, { ' name': 冒 华 为荣耀 V9 ' }, { ' name 勺 ' 华为荣耀 V9 ' } , { ' name 勺'华为荣耀 V9' } ] >
正向查询在数据库中只执行了 一次 SQL 查询。而反向查询通过 t[0].product_set.values(' name') 来获取模型Product 的数据,因此反向查询执行了两次 SQL 查询, 首先查询模型 Type 的数据,然后根据第一次查询的结果再查询与模型 Product 相互关联的数据。
为了减少反向查询的查询次数,我们可以使用 select related 方法实现, 该方法只 执行一次 SQL 查询就能达到反向查询的效果。 select related 使用方法如下:
功能 | 代码 | 等同SQL语句 |
查询模型 Product 的字段 name 和模型 Type 的字段 type_name | >>> Product.objects.select_related(' type ') .values( ' name ' , ' type__type_ name ') | SELECT name, type_narne FROM index_product INNER JOIN index type ON (type_id = id) |
查询两个模型的全部数据 | >>>Product.objects.select_related( ' type ' ).all() | SELECT * FROM index_product INNER JOIN index_type ON (type_id = id) |
获取两模型数据,以模型 Type 的 type name 字段等于手机为查询条件 | >>> Product.objects.select_related(' type') .filter(type__type_name= '手机 ').all() | SELECT * FROM index_product INNER JOIN inde_ type ON (type_id = id) WHERE index_type.type_name = , 手机 ' |
select related 的使用说明如下:
- 以模型 Product 作为查询对象主体,当然也可以使用模型 Type,只要两表之间 有外键关联即可。
- 设置 select_related的参数值为"type"该参数值是模型 Product定义的 type 字段。
- 如果在查询过程中 需要使用 另 一个数据表的字段, 可以使用"外键 字段名 " 来指向该表的字段。如 type_ type_name 代表由模型 Product 的外键 type 指向 模型 Type 的字段 type_ name, type 代表模型 Product 的外键 type, 双下画线" __" 代表连接符, type_name 是模型 Type 的字段。
select_related 还可以支持三个或三个以上的数据表同时查询:
p = Person.objects.select_related('living__province').get(name='张三')
p.living.province
上例中的living和provine是俩个外键。通过双下划线"__”连接起来。