对于数据的增删改查操作,我们除了使用Model自身的save(),delete(),clean(),还可以使用Manager类的实例对象来进行操作。

1. 添加数据

添加数据两种方法:

  • 创建模型类对象,执行对象的**save()**方法保存到数据库中去;
  • 通过**模型类.objects.create()**进行保存; ```sql 通过创建模型类对象,执行对象的save()方法保存到数据库中。

from book.models import BookInfo,PeopleInfo book = BookInfo( … name=’python入门’, … pub_date=’2010-1-1’ … ) book.save() # 由于继承了 book

  1. ```python
  2. PeopleInfo.objects.create(
  3. ... name='itheima',
  4. ... book=book
  5. ... )
  6. <PeopleInfo: itheima>

2. 修改数据

修改数据有两种方法:

  • 修改模型类对象的属性,然后执行**save()**方法;
  • 使用**模型类.objects.filter().update()**,返回受影响的行数。
    1. >>> person = PeopleInfo.objects.get(name='itheima')
    2. >>> person.name = 'itcast'
    3. >>> person.save()
    4. >>> person
    5. <PeopleInfo: itcast>
    1. >>> PeopleInfo.objects.filter(name='小明').update(name='小黄')
    2. 1

    3. 删除数据

    删除也有两种方法:
  • 模型类对象的**delete()**方法
  • **模型类.objects.filter().delete()**
    1. >>> person = PeopleInfo.objects.get(name='小花')
    2. >>> person.delete()
    3. (1, {'book.PeopleInfo': 1})
    4. 2)模型类.objects.filter().delete()
    1. >>> BookInfo.objects.filter(name='python入门').delete()
    2. (1, {'book.BookInfo': 1, 'book.PeopleInfo': 0})

    4. 查询数据

    4.1 基础条件查询:使用Manager对象的方法[ get(),all(),count(), filter(),exclude()]

  1. **模型类.objects.get()/all()/count()** ```python

    BookInfo.objects.get(id=1)

BookInfo.objects.get(pk=2)

BookInfo.objects.get(pk=20) Traceback (most recent call last): File ““, line 1, in File “/home/python/.virtualenvs/py3_django_1.11/lib/python3.5/site-packages/django/db/models/manager.py”, line 85, in manager_method return getattr(self.get_queryset(), name)(args, *kwargs) File “/home/python/.virtualenvs/py3_django_1.11/lib/python3.5/site-packages/django/db/models/query.py”, line 380, in get self.model._meta.object_name book.models.DoesNotExist: BookInfo matching query does not exist.

BookInfo.objects.all()

, , , ]>

BookInfo.objects.count() 4 ```

  1. 过滤查询:返回的是一个QuerySet查询集,实现SQL中的where功能,包括filter过滤多个结果,exxclude排除掉符合条件剩下的结果,get过滤单一结果。过滤条件的使用,这三个方法都相同。而且还可以逐个调用表示逻辑与的关系 ```python

    BookInfo.objects.filter(readcountgt=20,idlt=3) ]>

或者

BookInfo.objects.filter(readcountgt=20).filter(idlt=3)

]> **过滤条件的表达式:**`**属性名称__比较运算符=值**`**,# 属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线**<br />**过滤条件所用的比较运算符:**python

比较运算符有:

  1. exact : 等于
  2. contains : 是否包含字符串 a. startwith、endwith:以指定值开头或结尾
  3. isnull: 是否为null
  4. in : 是否包含在范围内
  5. 比较查询: gt: 大于(great then) gte: 大于等于(great then equal) lt : 小于(less then) lte: 小于等于(less then equal) exclude():不等于
  6. 日期查询: year,month,day,week_day,hour,minute,second python 1.exact: 查询编号为1的图书 BookInfo.objects.filter(idexact=1) 可简写为: BookInfo.objects.filter(id=1) 2.contains: 查询书名包含’传’的图书。 BookInfo.objects.filter(namecontains=’传’) ]> 3.isnull: 查询书名为空的图书 BookInfo.objects.filter(name__isnull=True)
  7. in :查询编号为1或3或5的图书 BookInfo.objects.filter(id__in=[1,3,5]) , ]>
  8. 比较查询:查询编号大于3的图书 BookInfo.objects.filter(id__gt=3)
  9. 日期查询 BookInfo.objects.filter(pub_date__year=1980) ]> ```

    4.2 F与Q对象查询

  • 导包:**from django.db.models import F,Q**

F对象使用:

  • 语法:**filter(字段名_运算符=F('字段名'))**,可以在F对象上进行算术运算。
  • 使用场景:对象的属性与常量值之间使用一般的条件查询即可,但是对象的属性之间进行比较需要使用F对象。

Q对象使用:

  • 语法:**Q(属性名__运算符=值)**
  • 使用场景:实现条件逻辑与可以使用过滤器**filter**表示,但是使用Q对象不仅可以实现逻辑与,还可以实现逻辑或,逻辑非
  • 逻辑运算符:&(逻辑与)、|(逻辑或)、~(逻辑非) ```python
  1. 查询阅读量大于20的图书 BookInfo.objects.filter(Q(readcount__gt=20))

  2. 查询阅读量大于20,或编号小于3的图书 BookInfo.objects.filter(Q(readcountgt=20)|Q(idlt=3)) , , ]>

  3. 查询编号不等于3的图书 BookInfo.objects.filter(~Q(id=3)) , , ]>

  1. <a name="Tw5cn"></a>
  2. ## 4.3 聚合函数和排序函数
  3. 1. 聚合函数:使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg平均,Count数量,Max最大,Min最小,Sum求和。
  4. - 导包:`**from django.db.models import Sum**`
  5. - **aggregate()**的返回值是一个字典类型,格式如下:`**{'属性名__聚合类小写':值}**`
  6. ```python
  7. from django.db.models import Sum
  8. BookInfo.objects.aggregate(Sum('readcount'))
  9. {'readcount__sum': 126}
  1. 使用**order_by()**排序函数对结果进行排序 ```python

    默认升序

    BookInfo.objects.all().order_by(‘readcount’) , , , ]>

降序

BookInfo.objects.all().order_by(‘-readcount’)

, , , ]>

  1. <a name="rBWCr"></a>
  2. ## 4.4 关联查询
  3. <a name="KzYZy"></a>
  4. ### 4.4.1 多对一查询
  5. 1. 由一到多的访问语法:`**一对应的模型类对象.多对应的模型类名小写_set **`
  6. ```python
  7. # 查询书籍为1的所有人物信息
  8. >>> book = BookInfo.objects.get(id=1)
  9. >>> book.peopleinfo_set.all()
  10. <QuerySet [<PeopleInfo: 郭靖>, <PeopleInfo: 黄蓉>, <PeopleInfo: 黄药师>, <PeopleInfo: 欧阳锋>, <PeopleInfo: 梅超风>]>
  1. 由多到一的访问语法:**多对应的模型类对象.多对应的模型类中的关系类属性名**

    1. # 查询人物为1的书籍信息
    2. person = PeopleInfo.objects.get(id=1)
    3. person.book
    4. <BookInfo: 射雕英雄传>
  2. 关联过滤查询:

    1. 由多模型类条件查询一模型类数据:**关联模型类名小写__属性名__条件运算符=值**

      1. # 查询图书,要求图书人物为"郭靖"
      2. >>> book = BookInfo.objects.filter(peopleinfo__name='郭靖')
      3. >>> book
      4. <QuerySet [<BookInfo: 射雕英雄传>]>
    2. 由一模型类条件查询多模型类数据:**一模型类关联属性名__一模型类属性名__条件运算符=值**

      1. # 查询书名为“天龙八部”的所有人物
      2. >>> people = PeopleInfo.objects.filter(book__name='天龙八部')
      3. >>> people
      4. <QuerySet [<PeopleInfo: 乔峰>, <PeopleInfo: 段誉>, <PeopleInfo: 虚竹>, <PeopleInfo: 王语嫣>]>

      4.4.2 多对多查询

      通过例子讲解来多对多查询: ```python from django.db import models

class Goods(models.Model):#商品 g_name = models.CharField(max_length=20) g_price = models.DecimalField(max_digits=5, decimal_places=2) gc = models.ForeignKey(“Category”, null=True, on_delete=models.SET_NULL)#gc为外键,类别表为母表

class Category(models.Model):#类别 c_name = models.CharField(max_length=20)

class Store(models.Model):#商家 s_name = models.CharField(max_length=30) s_detail = models.TextField(blank=True, null=True) sc = models.ManyToManyField(“Category”)#与类别表进行多对多关联

  1. 查询:
  2. ```python
  3. 1.增
  4. 添加商家
  5. Store.objects.create(s_name="商家A", s_detail="物美价廉,抄底折扣。。。。")
  6. Out[2]: <Store: Store object>
  7. Store(s_name="商家B", s_detail="大促销").save()
  8. 添加类别
  9. Category.objects.create(c_name="电脑整机")
  10. <Category: Category object>
  11. Category(c_name="文具耗材").save()
  12. 增与改(增添子表或母表数据参照一对一的增,多对多重点在于关系表的对应关系变更)
  13. 创建商家C添加全部分类
  14. Store.objects.create(s_name="商家C").sc.add(*(Category.objects.all()))#如果商户已存在则把create改成get
  15. store = Store.objects.get(s_name="商家C")
  16. store.sc=(Category.objects.all())
  17. store.save()
  18. 创建商家D添加指定分类
  19. store = Store.objects.create(s_name="商家D")
  20. category = Category.objects.filter(c_name__in=["电脑整机","文具耗材"])#单个改成get,全部改成all
  21. store.sc.add(*category)#add是追加模式
  22. store.sc.clear()#清空此商家的商品
  23. #让指定商品分类添加指定的商家,反向查询
  24. store = Store.objects.create(s_name="商家E")
  25. category = Category.objects.get(c_name="电脑整机")
  26. category.store_set.add(store)
  27. 效果与上面一样
  28. 让所有商家都添加这个分类
  29. stores = Store.objects.all()
  30. category = Category.objects.get(c_name="电脑整机")
  31. category.store_set.add(*stores)
  32. category.store_set.clear()#让所有商家去除这个分类
  33. category.store_set.all().delete()#是删除store_set的所有商家
  34. #只有子表才有"子表名小写_set"的写法,得到的是一个QuerySet集合,后边可以接.add(),.remove(),.update(),.delete(),.clear()

4.5 查询集QuerySet

查询集,也称查询结果集、QuerySet,表示从数据库中获取的对象集合。当调用如下过滤器方法时,Django会返回查询集(而不是简单的列表):

  • all():返回所有数据。
  • filter():返回满足条件的数据。
  • exclude():返回满足条件之外的数据。
  • order_by():对结果进行排序。

从SQL的角度讲,查询集与select语句等价,过滤器像where、limit、order by子句

4.5.1 查询集有以下特性:

  • 惰性执行:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用。

    1. books = BookInfo.objects.all() # 并未进行数据库查询,只是创建了一个查询集books
    2. for book in books: # 执行遍历迭代操作后,才真正的进行了数据库的查询
    3. print(book.name)
  • 缓存:使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。 ```python

    如下是两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,增加了数据库的负载。

from book.models import BookInfo [book.id for book in BookInfo.objects.all()] [book.id for book in BookInfo.objects.all()]

经过存储后,可以重用查询集,第二次使用缓存中的数据。

books=BookInfo.objects.all() [book.id for book in books] [book.id for book in books]

  1. <a name="Nxlg9"></a>
  2. ### 4.5.2 限制查询集
  3. 可以对查询集进行取下标或切片操作,等同于sql中的limit和offset子句。(注意:不支持负数索引。)
  4. - 对查询集进行切片后返回一个新的查询集,不会立即执行查询。
  5. ```python
  6. # 获取前两个对象
  7. >>> books = BookInfo.objects.all()[0:2]
  8. >>> books
  9. <QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>]>

4.5.3 分页
导包:**from django.core.paginator import Paginator**

  1. #查询数据
  2. books = BookInfo.objects.all()
  3. #导入分页类
  4. from django.core.paginator import Paginator
  5. #创建分页实例
  6. paginator=Paginator(books,2)
  7. #获取指定页码的数据
  8. page_skus = paginator.page(1)
  9. #获取分页数据
  10. total_page=paginator.num_pages