Django知识4----models层
一、配置数据库
1.建立项目的数据库
create database blog;(示例:数据库名字是blog)
2.在setting文件中设置DATABASES
1 DATABASES = {
2 'default': {
3 'ENGINE': 'django.db.backends.mysql', # 改成mysql数据库。
4 'NAME': 'blog',
5 'USER': 'root',
6 'PASSWORD': '123',
7 'HOST': '127.0.0.1',
8 'PORT': '3306',
9 }
10 }
3.在应用的__init__.py文件中添加如下两行
作用:告诉django用pymysql模块来操作数据库,不然就会用默认的mysqldb模块来操作数据库了。
1 import pymysql
2 pymysql.install_as_MySQLdb()
4.在应用的models.py 文件中建立表的模型(定义类)
解释:类似一张Book的表,字段是id,title,author,publishDate,price,以及各个字段的类型和约束条件。
1 class Book(models.Model):
2 id = models.AutoField(primary_key=True)
3 title = models.CharField(max_length=32)
4 author = models.CharField(max_length=32)
5 publishDate = models.DateField()
6 price = models.DecimalField(max_digits=6,decimal_places=2)
5.建立了django的modle.py文件后,运行如下两条命令,在数据库中,按照表模型产生数据表
# 定义好模型,然后在终端执行两条命令来生成数据库。 python manage.py makemigrations
这时其实是在该app下建立 migrations目录,并记录下你所有的关于modes.py的改动,比如0001_initial.py, python manage.py migrate
接着执行migrate,这时候才真的把作用到数据库文件,产生对应的表.
二、model基础内容
1.ORM 映射关系
表名 <-------> 类名
字段 <-------> 属性
表记录 <------->类实例对象
2.单表操作
举例:现在有一个书籍的表(类名:Book)
2.1 添加记录、信息
方式一:(用save())
book_obj = models.Book(title='活着',author='yuan',publishDate='2015-10-23',price=23) # id设置了自增,可以不用添加 book_obj.save()
方式二:
current_obj = models.Book.objects.create(title='',author='',.......)
当前的current_obj就是现在新添加的对象,可以做一些操作。
2.2 修改记录、信息
#方式一:(效率高,推荐)
models.Book.objects.filter(id=1).update(title='',author='') # update()是queryset类型的方法
# 方式二
bool_obj = models.Book.objects.filter(id=0)[0]
book_obj.title ='new_name'
book_obj.save()
2.3 删除记录、信息
1 models.Book.objects.filter(id=id).delete()
2.4 查询记录、信息(重点)
Object与queryset的区别
# Object 指每条记录,是model类的实例对象
# queryset类型,是从数据库中查询到的每个对象的集合,类似列表。[obj1,obj2,obj3]
示例类的模型
#========models.py==========
from django.db import models
class Book(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
author = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=6,decimal_places=2)
def __str__(self):
return self.title
返回object对象类型的方法
1 models.Book.objects.get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
返回QuerySet类型的方法
1 models.Book.objects.all() 查询多有结果 # <QuerySet [<Book: 活着>, <Book: 水浒传>, <Book: 饿了>]> 类设置了__str__方法,
2 models.Book.objects.filter(title='yuan') # 查询满足title='yuan'的数据,返回QuerySet
3 models.Book.objects.exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
4 models.Book.objects.filter(author='yuan').values('id','title','author')
# 返回结果 <QuerySet [{'id': 1, 'title': '活着', 'author': 'yuan'}, {'id': 6, 'title': '饿了', 'author': 'yuan'}]>
5. models.Book.objects.filter(author='yuan').values_list('id','title','author')
# 返回结果:<QuerySet [(1, '活着', 'yuan'), (6, '饿了', 'yuan')]>
其他
1 <6> order_by(*field): 对查询结果排序
2
3 <7> reverse(): 对查询结果反向排序
4
5 <8> distinct(): 从返回结果中剔除重复纪录
6
7 <10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。
8
9 <11> first(): 返回第一条记录
10
11 <12> last(): 返回最后一条记录
12
13 <13> exists(): 如果QuerySet包含数据,就返回True,否则返回False
三、查询表记录
1.查询相关API
<1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个, 如果符合筛选条件的对象超过一个或者没有都会抛出错误。 <5> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <4> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列 <9> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <6> order_by(*field): 对查询结果排序 <7> reverse(): 对查询结果反向排序 <8> distinct(): 从返回结果中剔除重复纪录 <10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 <11> first(): 返回第一条记录 <12> last(): 返回最后一条记录 <13> exists(): 如果QuerySet包含数据,就返回True,否则返回False
2.基于对象的跨表查询
1 # ============基于对象的跨表查询============ 2 # 1.一对多关系 3 # 查询id=1的书籍的出版社所在的城市<br> 4 book_obj = models.Book.objects.filter(id=1).first() 5 ret = book_obj.publish.addr # book_obj.publish 拿到与这本书籍关联出版社的对象 6 7 # 查询 人民出版社出版过的所有书籍 8 publish_obj = models.Publish.objects.filter(name='清华出版社').first() 9 ret = publish_obj.book_set.all() # 反向查询,拿到书籍对象的集合 10 11 # 2.一对一查询 12 # 查询egon作者的手机号 13 author_obj = models.Author.objects.filter(name='egon').first() 14 ret = author_obj.author_detail.tel 15 16 # 查询所有住址在北京的作者的姓名 (反向查询) 17 # author_detail_obj = models.Author_detail.objects.filter(addr='北京') # 返回queryset类型 18 # for each in author_detail_obj: 19 # print(each.author.name) 20 21 22 # 3.多对多查询 23 # 红楼梦所有作者的名字以及手机号 24 # book_obj = models.Book.objects.filter(title='红楼梦').first() 25 # author_list = book_obj.author.all() # 拿到目前book对象关联的author对象的集合 26 # for each_author in author_list: 27 # print(each_author.name,each_author.author_detail.tel) 28 29 # 查询egon出过的所有书籍的名字 30 # author_obj = models.Author.objects.filter(name='egon').first() 31 # book_list = author_obj.book_set.all() # queryset类型,反向查询拿到egon相关联的book对象 32 # for each in book_list: 33 # print(each.title)
3.基于双下划线的跨表查询
1 # ==================基于双下划线的跨表查询============== 2 3 # 1.查询清华出版社出版过的所有书籍的名字与价格(一对多) 4 # 正向查询 按字段:publish 5 ret = models.Book.objects.filter(publish__name='清华出版社').values_list('title','price') 6 7 # 反向查询:按表名: book 8 ret = models.Publish.objects.filter(name='清华出版社').values_list('book__title','book__price') 9 10 11 # 2.查询egon出过的所有书籍的名字(多对多) 12 # 正向查询,按照字段author字段 13 ret = models.Book.objects.filter(author__name='egon').values_list('title') 14 15 # 反向查询 按表名: book 16 models.Author.objects.filter(name='egon').values_list('book__title') 17 18 19 # 3.查询清华出版社出版过的所有书籍的名字以及作者的姓名 20 # 正向查询 21 ret = models.Book.objects.filter(publish__name='清华出版社').values_list('title','author__name') 22 # print(ret) 23 # 反向查询 24 ret = models.Publish.objects.filter(name='清华出版社').values_list('book__title','book__author__name') 25 # print(ret) 26 27 28 # 4.手机号以123开头的作者出版过的所有书籍名称以及出版社名称 29 ret = models.Book.objects.filter(author__author_detail__tel__startswith=123).values_list('title','publish__name') 30 # print(ret)
4.聚合查询
1 # ===============聚合查询================= 2 from django.db.models import Avg,Max,Min,Count 3 # queryset.aggregate() 4 5 # 1.单个聚合查询 6 ret = models.Book.objects.all().aggregate(c = Avg('price')) 7 # print(ret) 8 9 # 2.多个聚合查询 10 ret = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price')) 11 # print(ret) # 结果:{'price__avg': 31.2, 'price__max': Decimal('55.00'), 'price__min': Decimal('13.00')}
5.分组查询
1 # 分组查询 2 # 为QuerySet中每一个对象都生成一个独立的汇总值。 3 # 1.统计每一本书的作者个数 4 # 用法:queryset.annotate(),返回的还是queryset类型 5 ret = models.Book.objects.all().annotate(author_num=Count('author')) 6 for each_obj in ret: 7 print(each_obj.title,each_obj.author_num) 8 9 10 # 2.统计每个出版社的最便宜的书 11 ret = models.Book.objects.values('publish__name').annotate(book_num=Count('title')) 12 # print(ret)
6. F、Q查询
1 # ==============F、Q查询================= 2 from django.db.models import F,Q 3 4 # 查询readNum大于wordsNum的书 5 ret = models.Book.objects.filter(readNum__gt=F("wordsNum")*1.5) 6 # print(ret) 7 8 # 修改操作也可以使用F函数, 比如将每一本书的价格提高30元 9 models.Book.objects.all().update(price=F("price")+30) 10 11 # Q查询 12 ret = models.Book.objects.filter(Q(author__name='yuan')|Q(author__name='egon')) 13 print(ret) 14 ret = models.Book.objects.filter(Q(author__name='yuan')|Q(author__name='egon')).distinct() 15 print(ret) 16 17 return HttpResponse("OK")