第六模块:WEB框架开发 第1章·Django框架开发50~87
- 51-表关系之一对多
- 52-表关系之多对多
- 53-表关系之一对一
- 54-数据库表关系之关联字段与外键约束
- 55-数据库表关系之sql创建关联表
- 56-ORM生成关联表模型
- 57-多表操作之一对多添加记录
- 58-多表操作之多对多添加记录
- 59-基于对象跨表查询简介
- 60-基于对象跨表查询之一对多
- 61-基于对象跨表查询之多对多
- 62-基于对象跨表查询之一对一
- 63-基于对象跨表查询之sql语句
- 64-基于双下划线的跨表查询之一对多1
- 65-基于双下划线的跨表查询之一对多2
- 66-基于双下划线的跨表查询之多对多1
- 67-基于双下滑线的跨表查询之多对多2
- 68-基于双下滑线的跨表查询之一对一
- 69-基于双下划线的跨表查询之连续跨表1
- 70-基于双下划线的跨表查询之连续跨表2
- 71-聚合查询
- 72-单表下的分组查询1
- 73-单表下的分组查询2
- 74-多表下的分组查询1
- 75-多表下的分组查询2
- 76-多表下的分组查询3
- 77-多表下的分组查询4
- 78-多表下的分组查询5
- 79-多表下的分组查询6
- 80-F查询和Q查询
- 81-多表操作的章节作业布置-基于多表的图书管理系统
- 82-基于多表的图书管理系统添加功能1
- 83-基于多表的图书管理系统添加功能2
- 84-基于多表的图书管理系统查看功能
- 85-基于多表的图书管理系统编辑功能1
- 86-基于多表的图书管理系统编辑功能2
- 87-基于多表的图书管理系统删除功能
51-表关系之一对多;
1、表关系之“一对多”;
即一张表中的一条记录,可对应另一张表中的多条记录;
2、为什么要使用多表?
减少冗余数据,提升查询效率;
3、总结;
1)一旦确认表关系是一对多后,在多对应的表中创建"关联字段";
52-表关系之多对多
1、表关系之多对多;
即两张表的关系为“双向的一对多或双向的多对一”;
2、总结;
1)一但确定表关系是“多对多”:创建第三张“关系表”,一般为3个字段;id、a_id、b_id;
53-表关系之一对一
1、表关系之“一对一”;
即本来两张表的字段分布在“两张表”中,彼此一 一对应,但有一个“关联字段”,关联字段的约束为unique;
2、总结;
1)关联字段写在那张表呢?哪张表都可以;
2)一旦确定关联关系是“一对一”:在两张表的任意一张表中建立“关联字段”+unique约束信息;
54-数据库表关系之关联字段与外键约束
1、一般建立完关联字段后,加上约束信息,比如外键约束;
2、但有的情况下,可以使用“逻辑意义上”的外键,即不加外键约束,但从业务代码的角度进行外键引用的使用;
具体情况,具体分析,各有利弊;
55-数据库表关系之sql创建关联表
56-ORM生成关系表模型
1、Publish、Book、Author、AuthorDetail、Book2Author表关系初识;
实例:我们来假定下面这些概念,字段和关系
1、作者模型:一个作者有姓名和年龄;
2、作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息,作者详情模型和作者模型之间是一对一的关系(one-to-one);
3、出版商模型:出版商有名称,所在城市以及email;
4、书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many),一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系;(one-to-many)。
2、创建models.py模型文件;
from django.db import models # Create your models here.
"""
Book--------Publish,一对多的关系;
AuthorDetail--------Author,一对一的关系,关联字段建立在哪里都行;
Book2Author,多对多关系; """
#作者详情表;
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
birthday = models.DateField()
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64)
#作者表;
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
authordetail = models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE) #出版社表;
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField() #书籍表;
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)
#一对多的关系;
publish =models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
"""
数据库迁移的时候,会翻译成SQL语句中的这两句话;
publish_id INT,
FOREIGN KEY (publish_id) REFERENCES publish(id)
""" #一对多的关系;
authors = models.ManyToManyField(to="Author") """
#CREATE TABLE book2author(
CREATE TABLE book_authors(
id INT PRIMAEY KEY auto_increment,
book_id INT,
author_id INT,
FOREIGN KEY (book_id) REFERENCES book(id),
FOREIGB KEY (autor_id) REFERENCES author(id)
);
""" #ORM中绑定多对多关系,不建议这么去创建,虽说可以以类的方式去创建,但不建议这么做;
# class Book2Author(models.Model):
# nid = models.AutoField(primary_key=True)
# book = models.ForeignKey(to="Book")
# author = models.ForeignKey(to="Author")
3、使用Pycharm自带sqllite客户端工具进行连接查看;
小结:
- 表的名称
myapp_modelName
,算了,我还是说人话吧,应用名_模型名称,比如app01_Book是根据模型中的元数据自动生成的,也可以覆写为别的名称; id
字段是自动添加的,可指定为nid或其他;- 对于外键字段,Django 会在关联字段名上添加"_id" 来创建数据库中的列名,所以我们的关联字段不再写成book_id的形式,直接为book,否则会出现book_id_id的尴尬形式;
- 这个例子中的
CREATE TABLE
SQL 语句使用PostgreSQL 语法格式,要注意的是Django会根据settings.py文件中指定的数据库类型来使用相应的SQL语句,默认为sqllite3,可指定为MySQL; - 定义好模型之后,你需要告诉Django 使用这些模型。我们要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加
models.py
所在应用的名称,比如app01; - 外键字段 ForeignKey有一个null=True的设置(它允许外键接收空值 NULL),我们可以赋给它空值 None ;
在Django2.0之后,出现OneToOneField、ForeignKey要在后面添加on_delete=models.CASCADE属性,否则报错;
57-多表操作之一对多添加记录
1、views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def add(request):
pub = Publish.objects.create(name="人民出版社",email="123@qq.com",city="北京") #方式1:
#为Book表绑定出版社"Book-------Publish;
book_obj = Book.objects.create(title="红楼梦",price=100,publishDate="2012-12-12",publish_id=1)
print(book_obj.title) #方式2:
pub_obj = Publish.objects.filter(nid=1).first()
book_obj= Book.objects.create(title="三国演义",price=100,publishDate="2018-08-18",publish=pub_obj)
print(book_obj.title)
print(book_obj.price)
print(book_obj.publishDate)
print(book_obj.publish)#与这本书关联的出版社对象;
print(book_obj.publish.name)#
print(book_obj.publish.email)#
print(book_obj.publish_id) #查询西游记的出版社的邮箱地址是什么?
book_obj=Book.objects.filter(title="西游记").first()
print("查询西游记的出版社的邮箱地址是什么?",book_obj.publish.email) return HttpResponse("OK")
58-多表操作之一对多添加纪录
1、一对多添加记录;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def add(request):
pub = Publish.objects.create(name="人民出版社",email="123@qq.com",city="北京") #方式1:
#为Book表绑定出版社"Book-------Publish;
# book_obj = Book.objects.create(title="红楼梦",price=100,publishDate="2012-12-12",publish_id=1)
# print(book_obj.title) #方式2:
# pub_obj = Publish.objects.filter(nid=1).first()
# book_obj= Book.objects.create(title="三国演义",price=100,publishDate="2018-08-18",publish=pub_obj)
# print(book_obj.title)
# print(book_obj.price)
# print(book_obj.publishDate)
# print(book_obj.publish)#与这本书关联的出版社对象;
# print(book_obj.publish.name)#
# print(book_obj.publish.email)#
# print(book_obj.publish_id) #查询西游记的出版社的邮箱地址是什么?
# book_obj=Book.objects.filter(title="西游记").first()
# print("查询西游记的出版社的邮箱地址是什么?",book_obj.publish.email) ##########################################多对多的关系##################################################################
book_obj = Book.objects.create(title="金梅",price=100,publishDate="2012-12-12",publish_id=1)
cxz = Author.objects.get(name="cxz")
ljp = Author.objects.get(name="ljp") #绑定多对多关系的API;
book_obj.authors.add(cxz,ljp)
#book_obj.authors.add(1,2,3)
#book_obj.authors.add(*[1,2,3]) #解除多对多关系的API;
book = Book.objects.filter(nid=2).first()
#book.authors.remove(2)
#book.authors.clear() print(book.authors.all()) #查询主键为4的书籍的所有作者的名字;
ret = book.authors.all().values("name")
print(ret) return HttpResponse("OK")
models.py;
from django.db import models # Create your models here. from django.db import models """
Book--------Publish,一对多的关系;
AuthorDetail--------Author,一对一的关系,关联字段建立在哪里都行;
Book2Author,多对多关系; """
#作者详情表;
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
birthday = models.DateField()
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64)
#作者表;
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
authordetail = models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)
def __str__(self):
return self.name #出版社表;
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField() def __str__(self):
return self.name #书籍表;
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)
#一对多的关系;
publish =models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
def __str__(self):
return self.title
"""
数据库迁移的时候,会翻译这两句话;
publish_id INT,
FOREIGN KEY (publish_id) REFERENCES publish(id)
""" #一对多的关系;
authors = models.ManyToManyField(to="Author") """
#CREATE TABLE book2author(
CREATE TABLE book_authors(
id INT PRIMAEY KEY auto_increment,
book_id INT,
author_id INT,
FOREIGN KEY (book_id) REFERENCES book(id),
FOREIGB KEY (autor_id) REFERENCES author(id)
);
""" #绑定多对多关系,不建议这么去创建;
# class Book2Author(models.Model):
# nid = models.AutoField(primary_key=True)
# book = models.ForeignKey(to="Book")
# author = models.ForeignKey(to="Author")
操作日志;
59-基于对象跨表查询简介
1、基于对象的跨表查询简介;
60-基于对象跨表查询之一对多
1、子查询和john查询;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request):
"""
跨表查询:
1、基于对象的查询;
2、基于双下划线的查询;
3、聚合与分组查询;
4、F与Q查询;
:param request:
:return:
"""
#1、基于对象的跨表查询;
#-----------------基于对象的跨表查询(子查询)-----------------------#
#一对多的正向查询;查询《西游记》这本书的出版社的名字
book_obj = Book.objects.filter(title = "西游记").first()
print(book_obj.publish)#与这本书关联的出版社对象;
print(book_obj.publish.name) #一对多的反向查询;查询出版社出版过的书籍的名称;
publish = Publish.objects.filter(name="人民出版社").first()
ret = publish.book_set.all()
print(ret) return HttpResponse("OK") """
关联属性在A表中:
正向查询:A--------->B;
反向查询:B--------->A; 关联属性在B表中:
正向查询:B--------->A;
反向查询:A--------->B; 1、一对多查询
正向查询:按照字段;
反向查询:表名小写_set.all();
book_obj.publish
Book(关联属性:publish)--------------->Publish
"""
操作日志:
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[19/Aug/2018 11:46:13] "GET /query/ HTTP/1.1" 200 2
人民出版社
(0.000) SELECT "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."title" = '西游记' ORDER BY "app01_book"."nid" ASC LIMIT 1; args=('西游记',)
人民出版社
(0.000) SELECT "app01_publish"."nid", "app01_publish"."name", "app01_publish"."city", "app01_publish"."email" FROM "app01_publish" WHERE "app01_publish"."nid" = 1; args=(1,)
<QuerySet [<Book: 红楼梦>, <Book: 西游记>, <Book: 三国演义>, <Book: 金梅>]>
(0.000) SELECT "app01_publish"."nid", "app01_publish"."name", "app01_publish"."city", "app01_publish"."email" FROM "app01_publish" WHERE "app01_publish"."name" = '人民出版社' ORDER BY "app01_publish"."nid" ASC LIMIT 1; args=('人民出版社',)
(0.001) SELECT "app01_book"."nid", "app01_book"."title", "app01_book"."publishDate", "app01_book"."price", "app01_book"."publish_id" FROM "app01_book" WHERE "app01_book"."publish_id" = 1 LIMIT 21; args=(1,)
[19/Aug/2018 11:46:55] "GET /query/ HTTP/1.1" 200 2
Performing system checks...
61-基于对象跨表查询之多对多
1、基于对象的跨表查询之多对多;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def add(request):
"""
绑定关系的视图;
:param request:
:return:
"""
pub = Publish.objects.create(name="人民出版社",email="123@qq.com",city="北京") #方式1:
#为Book表绑定出版社"Book-------Publish
# book_obj = Book.objects.create(title="红楼梦",price=100,publishDate="2012-12-12",publish_id=1)
# print(book_obj.title) #方式2:
# pub_obj = Publish.objects.filter(nid=1).first()
# book_obj= Book.objects.create(title="三国演义",price=100,publishDate="2018-08-18",publish=pub_obj)
# print(book_obj.title)
# print(book_obj.price)
# print(book_obj.publishDate)
# print(book_obj.publish)#与这本书关联的出版社对象;
# print(book_obj.publish.name)#
# print(book_obj.publish.email)#
# print(book_obj.publish_id) #查询西游记的出版社的邮箱地址是什么?
# book_obj=Book.objects.filter(title="西游记").first()
# print("查询西游记的出版社的邮箱地址是什么?",book_obj.publish.email) ##########################################多对多的关系##################################################################
book_obj = Book.objects.create(title="金梅",price=100,publishDate="2012-12-12",publish_id=1)
cxz = Author.objects.get(name="cxz")
ljp = Author.objects.get(name="ljp") #绑定多对多关系的API
book_obj.authors.add(cxz,ljp)
#book_obj.authors.add(1,2,3)
#book_obj.authors.add(*[1,2,3]) #解除多对多关系的API
book = Book.objects.filter(nid=2).first()
#book.authors.remove(2)
# book.authors.clear() print(book.authors.all()) #查询主键为4的书籍的所有作者的名字;
ret = book.authors.all().values("name")
print(ret) return HttpResponse("OK") def query(request):
"""
跨表查询:
1、基于对象的查询;
2、基于双下划线的查询;
3、聚合与分组查询;
4、F与Q查询;
:param request:
:return:
"""
##1、基于对象的跨表查询;
#------------------------------------------------------基于对象的跨表查询(子查询)-------------------------------------#
#一对多的正向查询;查询《西游记》这本书的出版社的名字
# book_obj = Book.objects.filter(title = "西游记").first()
# print(book_obj.publish)#与这本书关联的出版社对象;
# print(book_obj.publish.name) # #一对多的反向查询;查询出版社出版过的书籍的名称;
# publish = Publish.objects.filter(name="人民出版社").first()
# ret = publish.book_set.all()
# print(ret) #多对多查询的正向查询:查询《金梅》这本书的作者的名字;
book_obj = Book.objects.filter(title="金梅").first()
author_list = book_obj.authors.all()#Queryset对象; for author in author_list:
print(author.name) #多对多反向查询;查询cxz出版过的所有书籍名称;
cxz = Author.objects.filter(name="cxz").first()
book_list = cxz.book_set.all() for book in book_list:
print(book.title) return HttpResponse("OK") """
关联属性在A表中:
正向查询:A--------->B;
反向查询:B--------->A; 关联属性在B表中:
正向查询:B--------->A;
反向查询:A--------->B; 1、一对多查询
正向查询:按照字段;
反向查询:表名小写_set.all();
book_obj.publish
Book(关联属性:publish)--------------->Publish对象;
<----------------
publish_obj.book_set.all()#Queryset 2、多对多查询
正向查询:按照字段;
反向查询:表名小写_set.all(); book_obj.authors.all()
Book(关联属性:authors)--------------->Author对象
<----------------
author_obj.book_set.all()#Quertset对象;
"""
62-基于对象跨表查询之一对一
1、Author与AuthorDetail表存在一对一关系;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def add(request):
"""
绑定关系的视图;
:param request:
:return:
"""
pub = Publish.objects.create(name="人民出版社",email="123@qq.com",city="北京") #方式1:
#为Book表绑定出版社"Book-------Publish
# book_obj = Book.objects.create(title="红楼梦",price=100,publishDate="2012-12-12",publish_id=1)
# print(book_obj.title) #方式2:
# pub_obj = Publish.objects.filter(nid=1).first()
# book_obj= Book.objects.create(title="三国演义",price=100,publishDate="2018-08-18",publish=pub_obj)
# print(book_obj.title)
# print(book_obj.price)
# print(book_obj.publishDate)
# print(book_obj.publish)#与这本书关联的出版社对象;
# print(book_obj.publish.name)#
# print(book_obj.publish.email)#
# print(book_obj.publish_id) #查询西游记的出版社的邮箱地址是什么?
# book_obj=Book.objects.filter(title="西游记").first()
# print("查询西游记的出版社的邮箱地址是什么?",book_obj.publish.email) ##########################################多对多的关系##################################################################
book_obj = Book.objects.create(title="金瓶",price=100,publishDate="2012-12-12",publish_id=1)
cxz = Author.objects.get(name="cxz")
ljp = Author.objects.get(name="ljp") #绑定多对多关系的API
book_obj.authors.add(cxz,ljp)
#book_obj.authors.add(1,2,3)
#book_obj.authors.add(*[1,2,3]) #解除多对多关系的API
book = Book.objects.filter(nid=2).first()
#book.authors.remove(2)
# book.authors.clear() print(book.authors.all()) #查询主键为4的书籍的所有作者的名字;
ret = book.authors.all().values("name")
print(ret) return HttpResponse("OK") def query(request):
"""
跨表查询:
1、基于对象的查询;
2、基于双下划线的查询;
3、聚合与分组查询;
4、F与Q查询;
:param request:
:return:
"""
##1、基于对象的跨表查询;
#------------------------------------------------------基于对象的跨表查询(子查询)-------------------------------------#
#一对多的正向查询;查询《西游记》这本书的出版社的名字
# book_obj = Book.objects.filter(title = "西游记").first()
# print(book_obj.publish)#与这本书关联的出版社对象;
# print(book_obj.publish.name) # #一对多的反向查询;查询出版社出版过的书籍的名称;
# publish = Publish.objects.filter(name="人民出版社").first()
# ret = publish.book_set.all()
# print(ret) #多对多查询的正向查询:查询《金梅》这本书的作者的名字;
book_obj = Book.objects.filter(title="金梅").first()
author_list = book_obj.authors.all()#Queryset对象; for author in author_list:
print(author.name) #多对多反向查询;查询cxz出版过的所有书籍名称;
cxz = Author.objects.filter(name="cxz").first()
book_list = cxz.book_set.all() for book in book_list:
print(book.title) #一对一的正向查询:查询cxz的手机号
cxz = Author.objects.filter(name="cxz").first()
print(cxz.authordetail.telephone)
# 一对一的反向查询:查询手机号为138的作者的名字和年龄;
ad = AuthorDetail.objects.filter(telephone="").first()
print(ad.author.name)
print(ad.author.age) return HttpResponse("OK") """
关联属性在A表中:
正向查询:A--------->B;
反向查询:B--------->A; 关联属性在B表中:
正向查询:B--------->A;
反向查询:A--------->B; 1、一对多查询
正向查询:按照字段;
反向查询:表名小写_set.all();
book_obj.publish
Book(关联属性:publish)--------------->Publish对象;
<----------------
publish_obj.book_set.all()#Queryset 2、多对多查询
正向查询:按照字段;
反向查询:表名小写_set.all(); book_obj.authors.all()
Book(关联属性:authors)--------------->Author对象
<----------------
author_obj.book_set.all()#Quertset对象;
3、一对一查询
正向查询:按照字段
反向查询:表名小写 book_obj.authors.all()
Author(关联属性:authordetail)对象 ------------------------->AuthorDetail
<------------------------
authordetail.author #Queryset
"""
63-基于对象跨表查询之sql语句
64-基于双下划线的跨表查询之一对多1
1、基于上下滑线的跨表查询之一对多1;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------基于双下划线的跨表查询(join查询)---------------------------------------------------#
#一对多查询的正向查询:查询金梅这本书的出版社的名字;
ret = Book.objects.filter(title="金梅").values("publish__name")
print(ret)#<QuerySet [{'publish__name': '人民出版社'}]> return HttpResponse("OK") """
基于双下划线的跨表查询(join查询)
正向查询按照字段,反向查询按表名小写;用来告诉ORM引擎join哪张表
"""
65-基于双下划线的跨表查询之一对多2
1、基于双下划线的跨表查询之一对多2;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------基于双下划线的跨表查询(join查询)---------------------------------------------------#
#一对多查询的正向查询:查询金梅这本书的出版社的名字;
#方式1:
ret1 = Book.objects.filter(title="金梅").values("publish__name")
print(ret1)#<QuerySet [{'publish__name': '人民出版社'}]>
#方式2:
ret2 = Publish.objects.filter(book__title="金梅").values("name")
print(ret2)
return HttpResponse("OK") """
基于双下划线的跨表查询(join查询)
正向查询按照字段,反向查询按表名小写;用来告诉ORM引擎join哪张表
"""
SQL语句;
--查询金瓶这本书的出版社的名字 select app01_publish.name from app01_book inner join app01_publish
on app01_book.publish_id = app01_publish.nid
where app01_book.title = "金梅"
66-基于双下划线的跨表查询之多对多1
1、基于双下划线的跨表查询之多对多1;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------基于双下划线的跨表查询(join查询)---------------------------------------------------#
#一对多查询的正向查询:查询金梅这本书的出版社的名字;
#方式1:
ret1 = Book.objects.filter(title="金梅").values("publish__name")
print(ret1)#<QuerySet [{'publish__name': '人民出版社'}]>
#方式2:
ret2 = Publish.objects.filter(book__title="金梅").values("name")
print(ret2)
#多对多查询:查询金梅这本书的所有作者的名字;
#方式3:
ret3 = Book.objects.filter(title="金梅").values("authors__name")
print(ret3) return HttpResponse("OK") """
基于双下划线的跨表查询(join查询)
正向查询按照字段,反向查询按表名小写;用来告诉ORM引擎join哪张表
"""
SQL语句;
--需求:查询金梅这本书的所有作者的名字;
select app01_author.name from app01_book inner join app01_book_authors on app01_book.nid = app01_book_authors.book_id inner join app01_author
on app01_book_authors.author_id = app01_author.nid
where app01_book.title="金梅"
67-基于双下滑线的跨表查询之多对多2
1、基于双下划线的跨表查询之多对多2;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------基于双下划线的跨表查询(join查询)---------------------------------------------------#
#一对多查询的正向查询:查询金梅这本书的出版社的名字;
#方式1:
ret1 = Book.objects.filter(title="金梅").values("publish__name")
print(ret1)#<QuerySet [{'publish__name': '人民出版社'}]>
#方式2:
ret2 = Publish.objects.filter(book__title="金梅").values("name")
print(ret2)
#多对多查询:
#查询金梅这本书的所有作者的名字;
#需求:通过Book表join与其关联的Author表;属于正向查询,按照字段authors通知ORM引擎join book_authors与author #方式3:
ret3 = Book.objects.filter(title="金梅").values("authors__name")
print(ret3)
#方式4:
#需求:通过Author表join与其关联的Book表:
ret4 = Author.objects.filter(book__title="金梅").values("name")
print(ret4) return HttpResponse("OK") """
基于双下划线的跨表查询(join查询)
正向查询按照字段,反向查询按表名小写;用来告诉ORM引擎join哪张表
"""
操作日志:
System check identified no issues (0 silenced).
(0.001)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.001) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
August 19, 2018 - 14:56:38
Django version 2.1, using settings 'ORM2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
<QuerySet [{'publish__name': '人民出版社'}]>
(0.000) SELECT "app01_publish"."name" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
<QuerySet [{'name': '人民出版社'}]>
<QuerySet [{'authors__name': 'cxz'}]>
<QuerySet [{'name': 'cxz'}]>
(0.000) SELECT "app01_publish"."name" FROM "app01_publish" INNER JOIN "app01_book" ON ("app01_publish"."nid" = "app01_book"."publish_id") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
(0.000) SELECT "app01_author"."name" FROM "app01_book" LEFT OUTER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id") LEFT OUTER JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."nid") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
(0.000) SELECT "app01_author"."name" FROM "app01_author" INNER JOIN "app01_book_authors" ON ("app01_author"."nid" = "app01_book_authors"."author_id") INNER JOIN "app01_book" ON ("app01_book_authors"."book_id" = "app01_book"."nid") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
[19/Aug/2018 15:04:56] "GET /query/ HTTP/1.1" 200 2
68-基于双下滑线的跨表查询之一对一
1、基于双下滑线的跨表查询之一对一;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------基于双下划线的跨表查询(join查询)---------------------------------------------------#
#一对多查询的正向查询:查询金梅这本书的出版社的名字;
#方式1:
ret1 = Book.objects.filter(title="金梅").values("publish__name")
print(ret1)#<QuerySet [{'publish__name': '人民出版社'}]>
#方式2:
ret2 = Publish.objects.filter(book__title="金梅").values("name")
print(ret2)
#多对多查询:
#查询金梅这本书的所有作者的名字;
#需求:通过Book表join与其关联的Author表;属于正向查询,按照字段authors通知ORM引擎join book_authors与author
#方式4:
#方式3:
ret3 = Book.objects.filter(title="金梅").values("authors__name")
print(ret3) #需求:通过Author表join与其关联的Book表:
ret4 = Author.objects.filter(book__title="金梅").values("name")
print(ret4) #一对一的查询:查询cxz的手机号
#方式5:通过Author表与其关联的AuthorDetail表;属于正向查询,按照字段authordetail通知ORM引擎join AuthorDetail
ret5 = Author.objects.filter(name="cxz").values("authordetail__telephone")
print(ret5)#<QuerySet [{'authordetail__telephone': 138}]>
#方式6:通过AuthorDetail表与其关联的Author表;属于反向查询,按照表名小写author通知ORM引擎join Author
ret6 = AuthorDetail.objects.filter(author__name="cxz").values("telephone")
print(ret6)
return HttpResponse("OK") """
System check identified no issues (0 silenced).
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
August 19, 2018 - 15:12:42
Django version 2.1, using settings 'ORM2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
<QuerySet [{'publish__name': '人民出版社'}]>
(0.001) SELECT "app01_publish"."name" FROM "app01_book" INNER JOIN "app01_publish" ON ("app01_book"."publish_id" = "app01_publish"."nid") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
<QuerySet [{'name': '人民出版社'}]>
<QuerySet [{'authors__name': 'cxz'}]>
<QuerySet [{'name': 'cxz'}]>
<QuerySet [{'authordetail__telephone': 138}]>
<QuerySet [{'telephone': 138}]>
(0.000) SELECT "app01_publish"."name" FROM "app01_publish" INNER JOIN "app01_book" ON ("app01_publish"."nid" = "app01_book"."publish_id") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
(0.000) SELECT "app01_author"."name" FROM "app01_book" LEFT OUTER JOIN "app01_book_authors" ON ("app01_book"."nid" = "app01_book_authors"."book_id") LEFT OUTER JOIN "app01_author" ON ("app01_book_authors"."author_id" = "app01_author"."nid") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
(0.001) SELECT "app01_author"."name" FROM "app01_author" INNER JOIN "app01_book_authors" ON ("app01_author"."nid" = "app01_book_authors"."author_id") INNER JOIN "app01_book" ON ("app01_book_authors"."book_id" = "app01_book"."nid") WHERE "app01_book"."title" = '金梅' LIMIT 21; args=('金梅',)
(0.000) SELECT "app01_authordetail"."telephone" FROM "app01_author" INNER JOIN "app01_authordetail" ON ("app01_author"."authordetail_id" = "app01_authordetail"."nid") WHERE "app01_author"."name" = 'cxz' LIMIT 21; args=('cxz',)
(0.000) SELECT "app01_authordetail"."telephone" FROM "app01_authordetail" INNER JOIN "app01_author" ON ("app01_authordetail"."nid" = "app01_author"."authordetail_id") WHERE "app01_author"."name" = 'cxz' LIMIT 21; args=('cxz',)
[19/Aug/2018 15:12:50] "GET /query/ HTTP/1.1" 200 2 """ """
基于双下划线的跨表查询(join查询)
正向查询按照字段,反向查询按表名小写;用来告诉ORM引擎join哪张表
"""
69-基于双下划线的跨表查询之连续跨表1
# 进阶练习: # 练习: 手机号以110开头的作者出版过的所有书籍名称以及书籍出版社名称 # 方式1:
# 需求: 通过Book表join AuthorDetail表, Book与AuthorDetail无关联,所以必需连续跨表;
# ret=Book.objects.filter(authors__authordetail__telephone__startswith="110").values("title","publish__name")
# print(ret)
#
# # 方式2:
# ret=Author.objects.filter(authordetail__telephone__startswith="110").values("book__title","book__publish__name")
# print(ret)
70-基于双下划线的跨表查询之连续跨表2
71-聚合查询
1、ORM下的聚合查询;
- Avg();
- Count();
- Max();
- Min();
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print(ret)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')}
return HttpResponse("查询成功!")
""" """
操作日志:
"D:\Program\PyCharm 2018.1.4\bin\runnerw.exe" C:\Users\TQTL911\PycharmProjects\ORM2\venv\Scripts\python.exe C:/Users/TQTL911/PycharmProjects/ORM2/manage.py runserver 8000
Performing system checks... System check identified no issues (0 silenced).
(0.002)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
August 19, 2018 - 17:07:15
Django version 2.1, using settings 'ORM2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
(0.000) SELECT AVG("app01_book"."price") AS "avg_price", CAST(MAX("app01_book"."price") AS NUMERIC) AS "max_price", CAST(MIN("app01_book"."price") AS NUMERIC) AS "Min_price" FROM "app01_book"; args=()
{'avg_price': 100.0, 'max_price': Decimal(''), 'Min_price': Decimal('')}
[19/Aug/2018 17:07:16] "GET /query/ HTTP/1.1" 200 15
Not Found: /favicon.ico
[19/Aug/2018 17:07:16] "GET /favicon.ico HTTP/1.1" 404 2076
{'avg_price': 71.0, 'max_price': Decimal(''), 'Min_price': Decimal('')}
(0.000) SELECT AVG("app01_book"."price") AS "avg_price", CAST(MAX("app01_book"."price") AS NUMERIC) AS "max_price", CAST(MIN("app01_book"."price") AS NUMERIC) AS "Min_price" FROM "app01_book"; args=()
[19/Aug/2018 17:07:49] "GET /query/ HTTP/1.1" 200 15
Performing system checks... System check identified no issues (0 silenced).
(0.001)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
August 19, 2018 - 17:08:20
Django version 2.1, using settings 'ORM2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Performing system checks... System check identified no issues (0 silenced).
August 19, 2018 - 17:25:28
Django version 2.1, using settings 'ORM2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
72-单表下的分组查询1
1、单表下的分组查询1;
README.md文件;
#####################################--单表的分组查询--#######################################################
单表的分组查询: #查询每一个部门名称以及对应的员工数;
emp:
id name age salary dep
1 alex 12 2000 销售部
2 egon 22 3000 人事部
3 wen 22 5000 人事部 SQL语句:
select dep,Count(*) from emp group by dep; 思考:如使使用Django自带的ORM进行分组查询?
models.py,不能忘记执行迁移数据库命令;
from django.db import models # Create your models here. class Emp(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
salary = models.DecimalField(max_digits=8,decimal_places=2)
dep = models.CharField(max_length=32)
province =models.CharField(max_length=32)
1)执行迁移数据库命令;
Microsoft Windows [版本 10.0.17134.1]
(c) 2018 Microsoft Corporation。保留所有权利。 (venv) C:\Users\TQTL911\PycharmProjects\ORM2>python manage.py makemigrations
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
Migrations for 'app01':
app01\migrations\0002_emp.py
- Create model Emp (venv) C:\Users\TQTL911\PycharmProjects\ORM2>python manage.py migrate
(0.001)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
Operations to perform:
Apply all migrations: admin, app01, auth, contenttypes, sessions
Running migrations:
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) PRAGMA foreign_keys = OFF; args=None
(0.000) BEGIN; args=None
CREATE TABLE "app01_emp" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(32) NOT NULL, "age" integer NOT NULL, "salary" decimal NOT NULL, "dep" varchar(32) NOT NULL, "province" varchar(32)
NOT NULL); (params None)
(0.002) CREATE TABLE "app01_emp" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(32) NOT NULL, "age" integer NOT NULL, "salary" decimal NOT NULL, "dep" varchar(32) NOT NULL, "province" varc
har(32) NOT NULL); args=None
(0.000) PRAGMA foreign_keys = ON; args=None
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.000) BEGIN; args=None
(0.001) INSERT INTO "django_migrations" ("app", "name", "applied") VALUES ('app01', '0002_emp', '2018-08-19 10:12:31.599829'); args=['app01', '0002_emp', '2018-08-19 10:12:31.599829']
Applying app01.0002_emp... OK
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.001) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'admin' AND "django_content_
type"."model" = 'logentry'); args=('admin', 'logentry')
(0.000) SELECT "auth_permission"."content_type_id", "auth_permission"."codename" FROM "auth_permission" INNER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id")
WHERE "auth_permission"."content_type_id" IN (1) ORDER BY "django_content_type"."app_label" ASC, "django_content_type"."model" ASC, "auth_permission"."codename" ASC; args=(1,)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = 'admin'; args=('admin',)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'auth' AND "django_content_t
ype"."model" = 'permission'); args=('auth', 'permission')
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'auth' AND "django_content_t
ype"."model" = 'group'); args=('auth', 'group')
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'auth' AND "django_content_t
ype"."model" = 'user'); args=('auth', 'user')
(0.000) SELECT "auth_permission"."content_type_id", "auth_permission"."codename" FROM "auth_permission" INNER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id")
WHERE "auth_permission"."content_type_id" IN (2, 3, 4) ORDER BY "django_content_type"."app_label" ASC, "django_content_type"."model" ASC, "auth_permission"."codename" ASC; args=(2, 3, 4)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = 'auth'; args=('auth',)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'contenttypes' AND "django_c
ontent_type"."model" = 'contenttype'); args=('contenttypes', 'contenttype')
(0.000) SELECT "auth_permission"."content_type_id", "auth_permission"."codename" FROM "auth_permission" INNER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id")
WHERE "auth_permission"."content_type_id" IN (5) ORDER BY "django_content_type"."app_label" ASC, "django_content_type"."model" ASC, "auth_permission"."codename" ASC; args=(5,)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = 'contenttypes'; args=('conten
ttypes',)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'sessions' AND "django_conte
nt_type"."model" = 'session'); args=('sessions', 'session')
(0.000) SELECT "auth_permission"."content_type_id", "auth_permission"."codename" FROM "auth_permission" INNER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id")
WHERE "auth_permission"."content_type_id" IN (6) ORDER BY "django_content_type"."app_label" ASC, "django_content_type"."model" ASC, "auth_permission"."codename" ASC; args=(6,)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = 'sessions'; args=('sessions',
)
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'app01' AND "django_content_
type"."model" = 'author'); args=('app01', 'author')
(0.001) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'app01' AND "django_content_
type"."model" = 'authordetail'); args=('app01', 'authordetail')
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'app01' AND "django_content_
type"."model" = 'book'); args=('app01', 'book')
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'app01' AND "django_content_
type"."model" = 'publish'); args=('app01', 'publish')
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'app01' AND "django_content_
type"."model" = 'emp'); args=('app01', 'emp')
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'app01' AND "django_content_
type"."model" = 'emp'); args=('app01', 'emp')
(0.000) BEGIN; args=None
(0.001) INSERT INTO "django_content_type" ("app_label", "model") VALUES ('app01', 'emp'); args=['app01', 'emp']
(0.001) SELECT "auth_permission"."content_type_id", "auth_permission"."codename" FROM "auth_permission" INNER JOIN "django_content_type" ON ("auth_permission"."content_type_id" = "django_content_type"."id")
WHERE "auth_permission"."content_type_id" IN (7, 8, 9, 10, 11) ORDER BY "django_content_type"."app_label" ASC, "django_content_type"."model" ASC, "auth_permission"."codename" ASC; args=(7, 8, 9, 10, 11)
(0.000) BEGIN; args=None
(0.001) INSERT INTO "auth_permission" ("name", "content_type_id", "codename") SELECT 'Can add emp', 11, 'add_emp' UNION ALL SELECT 'Can change emp', 11, 'change_emp' UNION ALL SELECT 'Can delete emp', 11, '
delete_emp' UNION ALL SELECT 'Can view emp', 11, 'view_emp'; args=('Can add emp', 11, 'add_emp', 'Can change emp', 11, 'change_emp', 'Can delete emp', 11, 'delete_emp', 'Can view emp', 11, 'view_emp')
(0.000) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE "django_content_type"."app_label" = 'app01'; args=('app01',) (venv) C:\Users\TQTL911\PycharmProjects\ORM2>
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------#
#示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3) return HttpResponse("查询成功!")
""" """
操作日志:
System check identified no issues (0 silenced).
August 19, 2018 - 18:25:45
Django version 2.1, using settings 'ORM2.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
(0.000)
SELECT name, type FROM sqlite_master
WHERE type in ('table', 'view') AND NOT name='sqlite_sequence'
ORDER BY name; args=None
(0.001) SELECT "django_migrations"."app", "django_migrations"."name" FROM "django_migrations"; args=()
(0.001) SELECT AVG("app01_book"."price") AS "avg_price", CAST(MAX("app01_book"."price") AS NUMERIC) AS "max_price", CAST(MIN("app01_book"."price") AS NUMERIC) AS "Min_price" FROM "app01_book"; args=()
查询所有书籍的平均价格; {'avg_price': 71.0, 'max_price': Decimal(''), 'Min_price': Decimal('')}
(0.000) SELECT "app01_emp"."dep", AVG("app01_emp"."salary") AS "avg_salary" FROM "app01_emp" GROUP BY "app01_emp"."dep" LIMIT 21; args=()
查询每一个部门的名称以及员工的平均薪水: <QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]>
(0.000) SELECT "app01_emp"."province", COUNT("app01_emp"."id") AS "c" FROM "app01_emp" GROUP BY "app01_emp"."province" LIMIT 21; args=()
查询每一个身份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
[19/Aug/2018 18:25:49] "GET /query/ HTTP/1.1" 200 15
73-单表下的分组查询2
1、单表下的分组查询2;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------#
#示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3)#查询每一个省份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
#补充知识点:
ret4 = Emp.objects.all()
print(ret4)#select * from emp;
ret5 = Emp.objects.all().values("name")
print(ret5)#select name from emp;
return HttpResponse("查询成功!")
"""
小结:
1、在单表分组下,按照主键分组,是没有意义的!
"""
74-多表下的分组查询1
75-多表下的分组查询2
1、多表下的分组查询2;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------# #示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3)#查询每一个省份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
#补充知识点:
ret4 = Emp.objects.all()
print(ret4)#select * from emp;
ret5 = Emp.objects.all().values("name")
print(ret5)#select name from emp; #2 查询每一个出版社的名称以及出版的书籍的个数;
ret6 = Publish.objects.values("nid").annotate(c = Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret6)#查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'nid': 1, 'c': 4}, {'nid': 2, 'c': 0}]> ret7 = Publish.objects.values("name").annotate(c=Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret7) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}]> ret8 = Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
print("查询每一个出版社的名称以及出版的书籍的个数", ret8) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}, {'name': '人民出版社', 'c': 0}]> return HttpResponse("查询成功!") """
1 查询每一个出版社的书籍的个数
Book.objects.values("publish_id").annotate(Count("id")) 2 查询每一个出版社的名称以及出版的书籍的个数
Join SQL:select * from Book inner join Publish on book.publish_id = publish.id id title date price publish_id publish.id publish.name publish.addr publish.email
1 红楼梦 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
2 西游记 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
3 三国演义 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
4 金瓶 2012-12-12 101 1 1 南京民出版社 南京 345@163.com 分组查询的SQL语句:
select publish.name,Count("title") from Book inner join Publish on book.publish_id = publish.id group by publish.id;
思考:如何使用Django 的ORM进行书写查询语句,进行跨表分组查询; 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
小结:
1、在单表分组下,按照主键分组,是没有意义的!
1、在多表分组下,按照主键分组,是有意义的! """
76-多表下的分组查询3
1、多表下的分组查询3;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------# #示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3)#查询每一个省份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
#补充知识点:
ret4 = Emp.objects.all()
print(ret4)#select * from emp;
ret5 = Emp.objects.all().values("name")
print(ret5)#select name from emp; #2 查询每一个出版社的名称以及出版的书籍的个数
ret6 = Publish.objects.values("nid").annotate(c = Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret6)#查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'nid': 1, 'c': 4}, {'nid': 2, 'c': 0}]> ret7 = Publish.objects.values("name").annotate(c=Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret7) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}]> ret8 = Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
print("查询每一个出版社的名称以及出版的书籍的个数", ret8) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}, {'name': '人民出版社', 'c': 0}]> #查询每个作者的名字以及出版过的书籍的最高价格;
ret9 = Author.objects.values("pk").annotate(max_price = Max("book__price")).values("name","max_price")
print("查询每个作者的名字以及出版过的书籍的最高价格;",ret9)#查询每个作者的名字以及出版过的书籍的最高价格; <QuerySet [{'name': 'alex', 'max_price': Decimal('301')}, {'name': 'egon', 'max_price': Decimal('301')}]>
return HttpResponse("查询成功!") """
1 查询每一个出版社的书籍的个数
Book.objects.values("publish_id").annotate(Count("id")) 2 查询每一个出版社的名称以及出版的书籍的个数
Join SQL:select * from Book inner join Publish on book.publish_id = publish.id id title date price publish_id publish.id publish.name publish.addr publish.email
1 红楼梦 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
2 西游记 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
3 三国演义 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
4 金瓶 2012-12-12 101 1 1 南京民出版社 南京 345@163.com 分组查询的SQL语句:
select publish.name,Count("title") from Book inner join Publish on book.publish_id = publish.id group by publish.id;
思考:如何使用Django 的ORM进行书写查询语句,进行跨表分组查询; 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
跨表的分组查询模型:
每个后面表的模型.objects.values("pk).annotate(聚合函数(关联表__统计字段)).values("xxx","xxx")
小结:
1、在单表分组下,按照主键分组,是没有意义的!
1、在多表分组下,按照主键分组,是有意义的! """
原生SQL语句:
--查询每个作者的名字以及出版过的书籍的最高价格;
SELECT MAX(app01_book.price),app01_author.name FROM app01_book
INNER JOIN app01_book_authors
ON app01_book.nid = app01_book_authors.book_id
INNER JOIN app01_author
ON app01_author.nid=app01_book_authors.author_id
77-多表下的分组查询4
1、多表下的分组查询4;
理解的时候建议使用原生SQL模拟,查询的时候,使用ORM;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------# #示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3)#查询每一个省份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
#补充知识点:
ret4 = Emp.objects.all()
print(ret4)#select * from emp;
ret5 = Emp.objects.all().values("name")
print(ret5)#select name from emp; #示例2 查询每一个出版社的名称以及出版的书籍的个数
ret6 = Publish.objects.values("nid").annotate(c = Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret6)#查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'nid': 1, 'c': 4}, {'nid': 2, 'c': 0}]> ret7 = Publish.objects.values("name").annotate(c=Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret7) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}]> ret8 = Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
print("查询每一个出版社的名称以及出版的书籍的个数", ret8) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}, {'name': '人民出版社', 'c': 0}]> #查询每个作者的名字以及出版过的书籍的最高价格;
ret9 = Author.objects.values("pk").annotate(max_price = Max("book__price")).values("name","max_price")
print("查询每个作者的名字以及出版过的书籍的最高价格;",ret9)#查询每个作者的名字以及出版过的书籍的最高价格; <QuerySet [{'name': 'alex', 'max_price': Decimal('301')}, {'name': 'egon', 'max_price': Decimal('301')}]>
#示例3:查询每一个书籍的名称以及对应的作者的个数;
ret10 = Book.objects.values("pk").annotate(c = Count("authors__name")).values("title","c")#<QuerySet [{'title': '红楼梦', 'c': 0}, {'title': '西游记', 'c': 0}, {'title': '三国演绎', 'c': 2}, {'title': '金梅', 'c': 2}]>
print(ret10)
return HttpResponse("查询成功!") """
1 查询每一个出版社的书籍的个数
Book.objects.values("publish_id").annotate(Count("id")) 2 查询每一个出版社的名称以及出版的书籍的个数
Join SQL:select * from Book inner join Publish on book.publish_id = publish.id id title date price publish_id publish.id publish.name publish.addr publish.email
1 红楼梦 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
2 西游记 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
3 三国演义 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
4 金瓶 2012-12-12 101 1 1 南京民出版社 南京 345@163.com 分组查询的SQL语句:
select publish.name,Count("title") from Book inner join Publish on book.publish_id = publish.id group by publish.id;
思考:如何使用Django 的ORM进行书写查询语句,进行跨表分组查询; 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
跨表的分组查询模型:
每个后面表的模型.objects.values("pk).annotate(聚合函数(关联表__统计字段)).values("xxx","xxx")
小结:
1、在单表分组下,按照主键分组,是没有意义的!
1、在多表分组下,按照主键分组,是有意义的! """
原生SQL;
--#示例3:查询每一个书籍的名称以及对应的作者的个数;
select app01_book.title,COUNT(app01_author.name) from app01_book
inner join app01_book_authors
on app01_book.nid = app01_book_authors.book_id
inner join app01_author
on app01_book_authors.author_id = app01_author.nid
group by app01_book.nid
78-多表下的分组查询5
1、多表下的分组查询5;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------# #示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3)#查询每一个省份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
#补充知识点:
ret4 = Emp.objects.all()
print(ret4)#select * from emp;
ret5 = Emp.objects.all().values("name")
print(ret5)#select name from emp; #示例2 查询每一个出版社的名称以及出版的书籍的个数
ret6 = Publish.objects.values("nid").annotate(c = Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret6)#查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'nid': 1, 'c': 4}, {'nid': 2, 'c': 0}]> ret7 = Publish.objects.values("name").annotate(c=Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret7) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}]> ret8 = Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
print("查询每一个出版社的名称以及出版的书籍的个数", ret8) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}, {'name': '人民出版社', 'c': 0}]> #查询每个作者的名字以及出版过的书籍的最高价格;
ret9 = Author.objects.values("pk").annotate(max_price = Max("book__price")).values("name","max_price")
print("查询每个作者的名字以及出版过的书籍的最高价格;",ret9)#查询每个作者的名字以及出版过的书籍的最高价格; <QuerySet [{'name': 'alex', 'max_price': Decimal('301')}, {'name': 'egon', 'max_price': Decimal('301')}]>
#示例3:查询每一个书籍的名称以及对应的作者的个数;
ret10 = Book.objects.values("pk").annotate(c = Count("authors__name")).values("title","c")#<QuerySet [{'title': '红楼梦', 'c': 0}, {'title': '西游记', 'c': 0}, {'title': '三国演绎', 'c': 2}, {'title': '金梅', 'c': 2}]>
print(ret10) #------------------跨表分组查询的另外一种玩法------------------------#
#示例1:查询每一个出版社的名称以及出版的书籍的个数;
ret11 = Publish.objects.values("nid").annotate(c = Count("book__title")).values("name","email")
print(ret11)#<QuerySet [{'name': '人民出版社', 'email': '123@qq.com'}, {'name': '南京出版社', 'email': '345@163.com'}]>
ret12 = Publish.objects.all().annotate(c = Count("book__title")).values("name","c","city")
print(ret12)#<QuerySet [{'name': '人民出版社', 'city': '北京', 'c': 3}, {'name': '南京出版社', 'city': '南京', 'c': 1}]>
return HttpResponse("查询成功!") """
1 查询每一个出版社的书籍的个数
Book.objects.values("publish_id").annotate(Count("id")) 2 查询每一个出版社的名称以及出版的书籍的个数
Join SQL:select * from Book inner join Publish on book.publish_id = publish.id id title date price publish_id publish.id publish.name publish.addr publish.email
1 红楼梦 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
2 西游记 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
3 三国演义 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
4 金瓶 2012-12-12 101 1 1 南京民出版社 南京 345@163.com 分组查询的SQL语句:
select publish.name,Count("title") from Book inner join Publish on book.publish_id = publish.id group by publish.id;
思考:如何使用Django 的ORM进行书写查询语句,进行跨表分组查询; 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
跨表的分组查询模型:
每个后面的表模型.objects.values("pk).annotate(聚合函数(关联表__统计字段)).values("xxx","xxx")
每个后面的表模型.objects.annotate(聚合函数(关联表__统计字段)).values("表模型的素有字段以及统计字段")
小结:
1、在单表分组下,按照主键分组,是没有意义的!
1、在多表分组下,按照主键分组,是有意义的! """
79-多表下的分组查询6
1、多表下的分组查询6;
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------# #示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3)#查询每一个省份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
#补充知识点:
ret4 = Emp.objects.all()
print(ret4)#select * from emp;
ret5 = Emp.objects.all().values("name")
print(ret5)#select name from emp; #示例2 查询每一个出版社的名称以及出版的书籍的个数
ret6 = Publish.objects.values("nid").annotate(c = Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret6)#查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'nid': 1, 'c': 4}, {'nid': 2, 'c': 0}]> ret7 = Publish.objects.values("name").annotate(c=Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret7) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}]> ret8 = Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
print("查询每一个出版社的名称以及出版的书籍的个数", ret8) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}, {'name': '人民出版社', 'c': 0}]> #查询每个作者的名字以及出版过的书籍的最高价格;
ret9 = Author.objects.values("pk").annotate(max_price = Max("book__price")).values("name","max_price")
print("查询每个作者的名字以及出版过的书籍的最高价格;",ret9)#查询每个作者的名字以及出版过的书籍的最高价格; <QuerySet [{'name': 'alex', 'max_price': Decimal('301')}, {'name': 'egon', 'max_price': Decimal('301')}]>
#示例3:查询每一个书籍的名称以及对应的作者的个数;
ret10 = Book.objects.values("pk").annotate(c = Count("authors__name")).values("title","c")#<QuerySet [{'title': '红楼梦', 'c': 0}, {'title': '西游记', 'c': 0}, {'title': '三国演绎', 'c': 2}, {'title': '金梅', 'c': 2}]>
print(ret10) #------------------------------------------------跨表分组查询的另外一种玩法-----------------------------------------#
#示例1:查询每一个出版社的名称以及出版的书籍的个数;
ret11 = Publish.objects.values("nid").annotate(c = Count("book__title")).values("name","email")
print(ret11)#<QuerySet [{'name': '人民出版社', 'email': '123@qq.com'}, {'name': '南京出版社', 'email': '345@163.com'}]>
ret12 = Publish.objects.all().annotate(c = Count("book__title")).values("name","c","city")
print(ret12)#<QuerySet [{'name': '人民出版社', 'city': '北京', 'c': 3}, {'name': '南京出版社', 'city': '南京', 'c': 1}]> #--------------------------------------------练习题------------------------------------------------#
#统计每一个以py开头的书籍的作者的个数
ret13 = Book.objects.filter(title__startswith="py").values("pk").annotate(c = Count("authors__name")).values("title","c")
print(ret13)#<QuerySet []>
ret14 = Book.objects.values("pk").annotate(c = Count("authors__name")).filter(c__gt = 1).values("title","c")
print(ret14)#<QuerySet [{'title': '三国演绎', 'c': 2}, {'title': '金梅', 'c': 2}]>
return HttpResponse("查询成功!") """
1 查询每一个出版社的书籍的个数
Book.objects.values("publish_id").annotate(Count("id")) 2 查询每一个出版社的名称以及出版的书籍的个数
Join SQL:select * from Book inner join Publish on book.publish_id = publish.id id title date price publish_id publish.id publish.name publish.addr publish.email
1 红楼梦 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
2 西游记 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
3 三国演义 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
4 金瓶 2012-12-12 101 1 1 南京民出版社 南京 345@163.com 分组查询的SQL语句:
select publish.name,Count("title") from Book inner join Publish on book.publish_id = publish.id group by publish.id;
思考:如何使用Django 的ORM进行书写查询语句,进行跨表分组查询; 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
跨表的分组查询模型:
每个后面的表模型.objects.values("pk).annotate(聚合函数(关联表__统计字段)).values("xxx","xxx")
每个后面的表模型.objects.annotate(聚合函数(关联表__统计字段)).values("表模型的素有字段以及统计字段")
小结:
1、在单表分组下,按照主键分组,是没有意义的!
1、在多表分组下,按照主键分组,是有意义的! """
分组查询的总结;
A-B
关联属性在A表中 正向查询: A------>B
反向查询: B------>A 基于对象的跨表查询(子查询) # 一对多查询
正向查询:按字段
反向查询:表名小写_set.all() book_obj.publish
Book(关联属性:publish)对象 --------------> Publish对象
<--------------
publish_obj.book_set.all() # queryset
# 多对多查询
正向查询:按字段
反向查询:表名小写_set.all() book_obj.authors.all()
Book(关联属性:authors)对象 ------------------------> Author对象
<------------------------
author_obj.book_set.all() # queryset # 一对一查询 正向查询:按字段
反向查询:表名小写 author.authordetail
Author(关联属性:authordetail)对象 ------------------------>AuthorDetail对象
<------------------------
authordetail.author 基于双下划线的跨表查询(join查询) key:正向查询按字段,反向查询按表名小写 单表的分组查询: 查询每一个部门名称以及对应的员工数
emp: id name age salary dep
1 alex 12 2000 销售部
2 egon 22 3000 人事部
3 wen 22 5000 人事部 sql : select Count(id) from emp group by dep; 思考:如何用ORM语法进行分组查询? # 单表分组查询的ORM语法: 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段")) 在单表分组下,按着主键进行group by是没有任何意义的. 跨表的分组查询: Book表 id title date price publish_id
1 红楼梦 2012-12-12 101 1
2 西游记 2012-12-12 101 1
3 三国演绎 2012-12-12 101 1
4 金梅 2012-12-12 301 2 Publish表
id name addr email
1 人民出版社 北京 123@qq.com
2 南京出版社 南京 345@163.com 1 查询每一个出版社出版的书籍个数
Book.objects.values("publish_id").annotate(Count("id")) 2 示例1 查询每一个出版社的名称以及出版的书籍个数
join sql : select * from Book inner join Publish on book.publish_id=publish.id id title date price publish_id publish.id publish.name publish.addr publish.email
1 红楼梦 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
2 西游记 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
3 三国演绎 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
4 金梅 2012-12-12 301 2 2 南京出版社 南京 345@163.com 分组查询sql:
select publish.name,Count("title") from Book inner join Publish on book.publish_id=publish.id
group by publish.id,publish.name,publish.addr,publish.email 思考:如何用ORM语法进行跨表分组查询 ret=Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
print(ret) 3 示例2 查询每一个作者的名字以及出版过的书籍的最高价格
ret=Author.objects.values("pk").annotate(max_price=Max("book__price")).values("name","max_price") 4 示例3 查询每一个书籍的名称以及对应的作者个数 ret=Book.objects.values("pk").annotate(c=Count("authors__name")).values("title","c")
print(ret) 5 总结:
# 总结 跨表的分组查询的模型:
# 每一个后的表模型.objects.values("pk").annotate(聚合函数(关联表__统计字段)).values("表模型的所有字段以及统计字段")
# 每一个后的表模型.objects.annotate(聚合函数(关联表__统计字段)).values("表模型的所有字段以及统计字段")
80-F查询和Q查询
1、models.py中,class新增字段,建议添加default=0;
from django.db import models # Create your models here. from django.db import models """
Book--------Publish,一对多的关系;
AuthorDetail--------Author,一对一的关系,关联字段建立在哪里都行;
Book2Author,多对多关系; """
#作者详情表;
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
birthday = models.DateField()
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64)
#作者表;
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField()
authordetail = models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)
def __str__(self):
return self.name #出版社表;
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField() def __str__(self):
return self.name
#xxx表;
class Emp(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
salary = models.DecimalField(max_digits=8,decimal_places=2)
dep = models.CharField(max_length=32)
province =models.CharField(max_length=32) #书籍表;
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)
#新增字段;
read_num = models.IntegerField(default=0)
comment_num = models.IntegerField(default=0)
#一对多的关系;
publish =models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
def __str__(self):
return self.title
"""
数据库迁移的时候,会翻译这两句话;
publish_id INT,
FOREIGN KEY (publish_id) REFERENCES publish(id)
""" #一对多的关系
authors = models.ManyToManyField(to="Author") """
#CREATE TABLE book2author(
CREATE TABLE book_authors(
id INT PRIMAEY KEY auto_increment,
book_id INT,
author_id INT,
FOREIGN KEY (book_id) REFERENCES book(id),
FOREIGB KEY (autor_id) REFERENCES author(id)
);
""" #绑定多对多关系,不这么去创建;
# class Book2Author(models.Model):
# nid = models.AutoField(primary_key=True)
# book = models.ForeignKey(to="Book")
# author = models.ForeignKey(to="Author")
再次重新执行数据库迁移操作语句:
Python manage.py makemigrations
python manage.py migrate
2、F和Q查询的使用场景;
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def query(request): #---------------------------------------聚合与分组查询------------------------------------------------------------------#
#-------------------------------------->聚合,aggregate:返回值是一个字段,不再是queryset
#查询所有书籍的平均价格;
from django.db.models import Avg,Count,Max,Min
ret1 = Book.objects.all().aggregate(avg_price = Avg("price"),max_price = Max("price"),Min_price = Min("price"))
print("查询所有书籍的平均价格;",ret1)#{'avg_price': 71.0, 'max_price': Decimal('100'), 'Min_price': Decimal('38')} #----------------------------------------------分组查询annotate,返回值queryset---------------------------------------# #示例1:
#单表的分组查询:
#查询每一个部门的名称以及员工的平均薪水!
#SQL语句:select dep,Avg(salary) from emp group by dep;
#单表分组查询的ORM语法:单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
ret2 = Emp.objects.values("dep").annotate(avg_salary = Avg("salary"))
print("查询每一个部门的名称以及员工的平均薪水:",ret2)#<QuerySet [{'dep': '保安部', 'avg_salary': 5000.0}, {'dep': '教学部', 'avg_salary': 51000.0}]> #示例2:查询每一个省份的名称,以及对应的员工数;
ret3 = Emp.objects.values("province").annotate(c = Count("id"))
print("查询每一个省份的名称,以及对应的员工数;",ret3)#查询每一个省份的名称,以及对应的员工数; <QuerySet [{'province': '山东省', 'c': 2}, {'province': '河北省', 'c': 1}]>
#补充知识点:
ret4 = Emp.objects.all()
print(ret4)#select * from emp;
ret5 = Emp.objects.all().values("name")
print(ret5)#select name from emp; #示例2 查询每一个出版社的名称以及出版的书籍的个数
ret6 = Publish.objects.values("nid").annotate(c = Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret6)#查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'nid': 1, 'c': 4}, {'nid': 2, 'c': 0}]> ret7 = Publish.objects.values("name").annotate(c=Count("book__title"))
print("查询每一个出版社的名称以及出版的书籍的个数",ret7) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}]> ret8 = Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","c")
print("查询每一个出版社的名称以及出版的书籍的个数", ret8) # 查询每一个出版社的名称以及出版的书籍的个数 <QuerySet [{'name': '人民出版社', 'c': 4}, {'name': '人民出版社', 'c': 0}]> #查询每个作者的名字以及出版过的书籍的最高价格;
ret9 = Author.objects.values("pk").annotate(max_price = Max("book__price")).values("name","max_price")
print("查询每个作者的名字以及出版过的书籍的最高价格;",ret9)#查询每个作者的名字以及出版过的书籍的最高价格; <QuerySet [{'name': 'alex', 'max_price': Decimal('301')}, {'name': 'egon', 'max_price': Decimal('301')}]>
#示例3:查询每一个书籍的名称以及对应的作者的个数;
ret10 = Book.objects.values("pk").annotate(c = Count("authors__name")).values("title","c")#<QuerySet [{'title': '红楼梦', 'c': 0}, {'title': '西游记', 'c': 0}, {'title': '三国演绎', 'c': 2}, {'title': '金梅', 'c': 2}]>
print(ret10) #------------------------------------------------跨表分组查询的另外一种玩法-----------------------------------------#
#示例1:查询每一个出版社的名称以及出版的书籍的个数;
ret11 = Publish.objects.values("nid").annotate(c = Count("book__title")).values("name","email")
print(ret11)#<QuerySet [{'name': '人民出版社', 'email': '123@qq.com'}, {'name': '南京出版社', 'email': '345@163.com'}]>
ret12 = Publish.objects.all().annotate(c = Count("book__title")).values("name","c","city")
print(ret12)#<QuerySet [{'name': '人民出版社', 'city': '北京', 'c': 3}, {'name': '南京出版社', 'city': '南京', 'c': 1}]> #--------------------------------------------练习题------------------------------------------------#
#统计每一个以py开头的书籍的作者的个数
ret13 = Book.objects.filter(title__startswith="py").values("pk").annotate(c = Count("authors__name")).values("title","c")
print(ret13)#<QuerySet []>
ret14 = Book.objects.values("pk").annotate(c = Count("authors__name")).filter(c__gt = 1).values("title","c")
print(ret14)#<QuerySet [{'title': '三国演绎', 'c': 2}, {'title': '金梅', 'c': 2}]> #---------------------------------------F查询和Q查询------------------------------------------------------#
from django.db.models import F,Q
ret15 = Book.objects.filter(comment_num__gt=F("read_num"))
print(ret15)
ret16 = Book.objects.all().update(price=F("price")+2)
print("图书价格上涨2元每本",ret16) ret17 = Book.objects.filter(Q(title = "红楼梦")|Q(price = 100))
#ret17 = Book.objects.filter(Q(title = "红楼梦")&Q(price = 100))
#ret17 = Book.objects.filter(~Q(title = "红楼梦")&~Q(price = 100))
ret17 = Book.objects.filter(Q(title = "红楼梦")|Q(price = 100))
#先放置Q,再放置其他字段,注意先后顺序
ret17 = Book.objects.filter(Q(title = "红楼梦")|Q(price = 100),comment_num=100)
print(ret17)
return HttpResponse("查询成功!")
"""
1 查询每一个出版社的书籍的个数
Book.objects.values("publish_id").annotate(Count("id")) 2 查询每一个出版社的名称以及出版的书籍的个数
Join SQL:select * from Book inner join Publish on book.publish_id = publish.id id title date price publish_id publish.id publish.name publish.addr publish.email
1 红楼梦 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
2 西游记 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
3 三国演义 2012-12-12 101 1 1 人民出版社 北京 123@qq.com
4 金瓶 2012-12-12 101 1 1 南京民出版社 南京 345@163.com 分组查询的SQL语句:
select publish.name,Count("title") from Book inner join Publish on book.publish_id = publish.id group by publish.id;
思考:如何使用Django 的ORM进行书写查询语句,进行跨表分组查询; 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
跨表的分组查询模型:
每个后面的表模型.objects.values("pk).annotate(聚合函数(关联表__统计字段)).values("xxx","xxx")
每个后面的表模型.objects.annotate(聚合函数(关联表__统计字段)).values("表模型的素有字段以及统计字段")
小结:
1、在单表分组下,按照主键分组,是没有意义的!
1、在多表分组下,按照主键分组,是有意义的! """
81-多表操作的章节作业布置-基于多表的图书管理系统
1、项目介绍;
82-基于多表的图书管理系统添加功能1
1、项目操作步骤:https://www.processon.com/view/link/5b7a420ee4b0f8477db9c3b0
settings.py;
"""
Django settings for bookms_02 project. Generated by 'django-admin startproject' using Django 2.1. For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/ For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
""" import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '0e$((-gvw%926f7$^17cln1n+#k2*7g^3aectpb^r!z157*vn&' # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'book.apps.BookConfig',
] MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ROOT_URLCONF = 'bookms_02.urls' TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
] WSGI_APPLICATION = 'bookms_02.wsgi.application' # Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
} # Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
] # Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [
os.path.join(BASE_DIR,"static")
]
urls.py;
"""bookms_02 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path from book import views
urlpatterns = [
path('admin/', admin.site.urls),
path('book/add', views.add_book),
]
views.py;
from django.shortcuts import render # Create your views here.
from .models import Publish,Author
#添加书籍;
def add_book(request): publish_list = Publish.objects.all()
author_list = Publish.objects.all() return render(request,"addbook.html",{"author_list":author_list,"publish_list":publish_list})
models.py;
from django.db import models # Create your models here. #作者表;
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField() #出版社;
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField() #书籍表;
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)#999.99
#与Publish表建立"一对多"的关系,外键字段建立在多的一方;
publish = models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
#与Author表建立多对多的关系,ManyToManyField可以建立两个模型中的任意一个,自动创建第三张表表;
authors = models.ManyToManyField(to="Author",)
addbook.html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
<!-- Bootstrap --> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/dist/css/bootstrap.css">
<!-- Bootstrap -->
<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
</head>
<body>
<h3>添加书籍</h3>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<label for="">名称</label>
<input type="text" name="title" class="form-control">
</div>
<div class="form-group">
<label for="">价格</label>
<input type="text" name="price" class="form-control">
</div>
<div class="form-group">
<label for="">出版日期</label>
<input type="text" name="pub_date" class="form-control">
</div>
<div class="form-group">
<label for="" >出版社</label >
<select name="publish" id="" class="form-control">
{% for publish in publish_list %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endfor %} </select>
</div>
<div class="form-group">
<label for="">作者</label>
<select name="authors" type="text" id="" multiple class="form-control">
{% for author in author_list %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endfor %} </select>
</div>
<input type="submit" class="btn btn-default">
</form>
</div>
</div>
</div>
</body>
</html>
83-基于多表的图书管理系统添加功能2
views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from .models import Publish,Author,Book
#添加书籍;
def add_book(request):
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish_id = request.POST.get("publish_id")
authors_id_list = request.POST.getlist("authors_id_list")
#向数据库写入数据;
book_obj = Book.objects.create(title=title,price=price,publishDate=pub_date,publish_id=publish_id)
#绑定多对多关系;
book_obj.authors.add(*authors_id_list)
#print(authors_id_list)
return HttpResponse("Sucess!") publish_list = Publish.objects.all()
author_list = Author.objects.all() return render(request,"addbook.html",{"author_list":author_list,"publish_list":publish_list})
addbook.html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
<!-- Bootstrap --> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/dist/css/bootstrap.css">
<!-- Bootstrap -->
<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
</head>
<body>
<h3>添加书籍</h3>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<label for="">名称</label>
<input type="text" name="title" class="form-control">
</div>
<div class="form-group">
<label for="">价格</label>
<input type="text" name="price" class="form-control">
</div>
<div class="form-group">
<label for="">出版日期</label>
<input type="date" name="pub_date" class="form-control">
</div>
<div class="form-group">
<label for="" >出版社</label >
<select name="publish_id" id="" class="form-control">
{% for publish in publish_list %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endfor %} </select>
</div>
<div class="form-group">
<label for="">作者</label>
<select name="authors_id_list" type="text" id="" multiple class="form-control">
{% for author in author_list %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endfor %} </select>
</div>
<input type="submit" class="btn btn-default">
</form>
</div>
</div>
</div>
</body>
</html>
84-基于多表的图书管理系统查看功能
1、urls.py中添加books;
"""bookms_02 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,re_path from book import views
urlpatterns = [
path('admin/', admin.site.urls),
path('book/add', views.add_book),
re_path('books/', views.books),
]
2、views.py中添加books视图函数;
from django.shortcuts import render,HttpResponse # Create your views here.
from .models import Publish,Author,Book
#添加书籍;
def add_book(request):
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish_id = request.POST.get("publish_id")
authors_id_list = request.POST.getlist("authors_id_list")
#向数据库写入数据;
book_obj = Book.objects.create(title=title,price=price,publishDate=pub_date,publish_id=publish_id)
#绑定多对多关系;
book_obj.authors.add(*authors_id_list)
#print(authors_id_list)
return HttpResponse("Sucess!") publish_list = Publish.objects.all()
author_list = Author.objects.all() return render(request,"addbook.html",{"author_list":author_list,"publish_list":publish_list}) def books(request):
book_list = Book.objects.all()
return render(request,"books.html",{"book_list":book_list})
3、templates下新增books.html页面;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>查看书籍</title>
<!-- Bootstrap --> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/dist/css/bootstrap.css">
<!-- Bootstrap -->
<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
</head>
<body>
<h3>添加书籍</h3>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>编号</th>
<th>书籍名称</th>
<th>书籍价格</th>
<th>出版日期</th>
<th>出版社</th>
<th>作者</th>
</tr>
</thead>
<tbody>
{% for book in book_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.title }}</td>
<td>{{ book.price }}</td>
<td>{{ book.publishDate|date:"Y-m-d" }}</td>
<td>{{ book.publish.name }}</td>
<td>
{% for author in book.authors.all %}
{% if forloop.last %}
<span>{{ author.name }}</span>
{% else %}
<span>{{ author.name }}</span>,
{% endif %}
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
4、查看页面显示效果;
85-基于多表的图书管理系统编辑功能1
1、editbook.html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑书籍</title>
<!-- Bootstrap --> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/dist/css/bootstrap.css">
<!-- Bootstrap -->
<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
</head>
<body>
<h3>编辑书籍</h3>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<label for="">名称</label>
<input type="text" name="title" class="form-control" value="{{ edit_book_obj.title }}">
</div>
<div class="form-group">
<label for="">价格</label>
<input type="text" name="price" class="form-control" value="{{ edit_book_obj.price }}">
</div>
<div class="form-group">
<label for="">出版日期</label>
<input type="date" name="pub_date" class="form-control" value="{{ edit_book_obj.publishDate|date:"Y-m-d" }}">
</div>
<div class="form-group">
<label for="" >出版社</label >
<select name="publish_id" id="" class="form-control" >
{% for publish in publish_list %}
{% if edit_book_obj.publish == publish %}
<option value="{{ publish.pk }}" selected>{{ publish.name }}</option>
{% else %}
<option value="{{ publish.pk }}" >{{ publish.name }}</option>
{% endif %}
{% endfor %} </select>
</div>
<div class="form-group">
<label for="">作者</label>
<select name="authors_id_list" type="text" id="" multiple class="form-control">
{% for author in author_list %}
{% if author in edit_book_obj.authors.all %}
<option selected value="{{ author.pk }}">{{ author.name }}</option>
{% else %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<input type="submit" class="btn btn-default">
</form>
</div>
</div>
</div>
</body>
</html>
2、views.py;
from django.shortcuts import render,HttpResponse # Create your views here.
from .models import Publish,Author,Book
#添加书籍;
def add_book(request):
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish_id = request.POST.get("publish_id")
authors_id_list = request.POST.getlist("authors_id_list")
#向数据库写入数据;
book_obj = Book.objects.create(title=title,price=price,publishDate=pub_date,publish_id=publish_id)
#绑定多对多关系;
book_obj.authors.add(*authors_id_list)
#print(authors_id_list)
return HttpResponse("Sucess!") publish_list = Publish.objects.all()
author_list = Author.objects.all() return render(request,"addbook.html",{"author_list":author_list,"publish_list":publish_list}) def books(request):
book_list = Book.objects.all()
return render(request,"books.html",{"book_list":book_list}) #编辑图书
def change_book(request,edit_book_id):
edit_book_obj = Book.objects.filter(pk=edit_book_id).first()
publish_list = Publish.objects.all()
author_list = Author.objects.all()
return render(request,"editbook.html",{"edit_book_obj":edit_book_obj,"publish_list":publish_list,"author_list":author_list})
86-基于多表的图书管理系统编辑功能2
1、编辑功能时候,set()方法的引入;
views.py;
from django.shortcuts import render,HttpResponse,redirect # Create your views here.
from .models import Publish,Author,Book
#添加书籍;
def add_book(request):
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish_id = request.POST.get("publish_id")
authors_id_list = request.POST.getlist("authors_id_list")
#向数据库写入数据;
book_obj = Book.objects.create(title=title,price=price,publishDate=pub_date,publish_id=publish_id)
#绑定多对多关系;
book_obj.authors.add(*authors_id_list)
#print(authors_id_list)
return HttpResponse("Sucess!") publish_list = Publish.objects.all()
author_list = Author.objects.all() return render(request,"addbook.html",{"author_list":author_list,"publish_list":publish_list}) def books(request):
book_list = Book.objects.all()
return render(request,"books.html",{"book_list":book_list}) #编辑图书
def change_book(request,edit_book_id):
edit_book_obj = Book.objects.filter(pk=edit_book_id).first()
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish_id = request.POST.get("publish_id")
authors_id_list = request.POST.getlist("authors_id_list")
# 向数据库更新写入数据;
"""
1、先做更新内容操作;
2、清空原有的值;
3、重新进行写入新的值;
"""
Book.objects.filter(pk=edit_book_id).update(title=title,price = price,publishDate=pub_date,publish_id=publish_id)
# edit_book_obj.authors.clear()
# edit_book_obj.authors.add(*authors_id_list)
#等价于以上两句,先清空再设置;
edit_book_obj.authors.set(authors_id_list)
#编辑完成后,点击提交按钮,redirect至books页面;
return redirect("/books/")
publish_list = Publish.objects.all()
author_list = Author.objects.all() return render(request,"editbook.html",{"edit_book_obj":edit_book_obj,"publish_list":publish_list,"author_list":author_list})
2、编辑完成后,redirect()重定向页面的引入;
return redirect("/books/")
87-基于多表的图书管理系统删除功能
urls.py;
"""bookms_02 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,re_path from book import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path('books/add/$', views.add_book),
re_path('books/$', views.books),
re_path('books/(\d+)/change/$', views.change_book),
re_path('books/(\d+)/delete/$', views.delete_book),
]
views.py;
from django.shortcuts import render,HttpResponse,redirect # Create your views here.
from .models import Publish,Author,Book
#添加书籍;
def add_book(request):
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish_id = request.POST.get("publish_id")
authors_id_list = request.POST.getlist("authors_id_list")
#向数据库写入数据;
book_obj = Book.objects.create(title=title,price=price,publishDate=pub_date,publish_id=publish_id)
#绑定多对多关系;
book_obj.authors.add(*authors_id_list)
#print(authors_id_list)
return redirect("/books/") publish_list = Publish.objects.all()
author_list = Author.objects.all() return render(request,"addbook.html",{"author_list":author_list,"publish_list":publish_list}) def books(request):
book_list = Book.objects.all()
return render(request,"books.html",{"book_list":book_list}) #编辑图书
def change_book(request,edit_book_id):
edit_book_obj = Book.objects.filter(pk=edit_book_id).first()
if request.method == "POST":
title = request.POST.get("title")
price = request.POST.get("price")
pub_date = request.POST.get("pub_date")
publish_id = request.POST.get("publish_id")
authors_id_list = request.POST.getlist("authors_id_list")
# 向数据库更新写入数据;
"""
1、先做更新内容操作;
2、清空原有的值;
3、重新进行写入新的值;
"""
Book.objects.filter(pk=edit_book_id).update(title=title,price = price,publishDate=pub_date,publish_id=publish_id)
# edit_book_obj.authors.clear()
# edit_book_obj.authors.add(*authors_id_list)
#等价于以上两句,先清空再设置;
edit_book_obj.authors.set(authors_id_list)
#编辑完成后,点击提交按钮,redirect至books页面;
return redirect("/books/")
publish_list = Publish.objects.all()
author_list = Author.objects.all() return render(request,"editbook.html",{"edit_book_obj":edit_book_obj,"publish_list":publish_list,"author_list":author_list}) def delete_book(request,delete_book_id):
Book.objects.filter(pk=delete_book_id).delete()
return redirect("/books/")
books.html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>查看书籍</title>
<!-- Bootstrap --> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/dist/css/bootstrap.css">
<!-- Bootstrap -->
<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
</head>
<body>
<h3>添加书籍</h3>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<a href="/books/add/" class="btn btn-primary">添加书籍</a>
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>编号</th>
<th>书籍名称</th>
<th>书籍价格</th>
<th>出版日期</th>
<th>出版社</th>
<th>作者</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book in book_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.title }}</td>
<td>{{ book.price }}</td>
<td>{{ book.publishDate|date:"Y-m-d" }}</td>
<td>{{ book.publish.name }}</td>
<td>
{% for author in book.authors.all %}
{% if forloop.last %}
<span>{{ author.name }}</span>
{% else %}
<span>{{ author.name }}</span>,
{% endif %}
{% endfor %}
</td>
<td>
<a href="books/{{ book.pk }}/change/" class="btn btn-warning">编辑</a>
<a href="books/{{ book.pk }}/delete/" class="btn btn-info">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
editbooks.html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编辑书籍</title>
<!-- Bootstrap --> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/dist/css/bootstrap.css">
<!-- Bootstrap -->
<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
</head>
<body>
<h3>编辑书籍</h3>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<label for="">名称</label>
<input type="text" name="title" class="form-control" value="{{ edit_book_obj.title }}">
</div>
<div class="form-group">
<label for="">价格</label>
<input type="text" name="price" class="form-control" value="{{ edit_book_obj.price }}">
</div>
<div class="form-group">
<label for="">出版日期</label>
<input type="date" name="pub_date" class="form-control" value="{{ edit_book_obj.publishDate|date:"Y-m-d" }}">
</div>
<div class="form-group">
<label for="" >出版社</label >
<select name="publish_id" id="" class="form-control" >
{% for publish in publish_list %}
{% if edit_book_obj.publish == publish %}
<option value="{{ publish.pk }}" selected>{{ publish.name }}</option>
{% else %}
<option value="{{ publish.pk }}" >{{ publish.name }}</option>
{% endif %}
{% endfor %} </select>
</div>
<div class="form-group">
<label for="">作者</label>
<select name="authors_id_list" type="text" id="" multiple class="form-control">
{% for author in author_list %}
{% if author in edit_book_obj.authors.all %}
<option selected value="{{ author.pk }}">{{ author.name }}</option>
{% else %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<input type="submit" class="btn btn-default">
</form>
</div>
</div>
</div>
</body>
</html>
addbook.html;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加书籍</title>
<!-- Bootstrap --> <link rel="stylesheet" type="text/css" href="/static/bootstrap-3.3.7/dist/css/bootstrap.css">
<!-- Bootstrap -->
<!--<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">-->
</head>
<body>
<h3>添加书籍</h3>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2"> <form action="" method="post">
{% csrf_token %}
<div class="form-group">
<label for="">名称</label>
<input type="text" name="title" class="form-control">
</div>
<div class="form-group">
<label for="">价格</label>
<input type="text" name="price" class="form-control">
</div>
<div class="form-group">
<label for="">出版日期</label>
<input type="date" name="pub_date" class="form-control">
</div>
<div class="form-group">
<label for="" >出版社</label >
<select name="publish_id" id="" class="form-control">
{% for publish in publish_list %}
<option value="{{ publish.pk }}">{{ publish.name }}</option>
{% endfor %} </select>
</div>
<div class="form-group">
<label for="">作者</label>
<select name="authors_id_list" type="text" id="" multiple class="form-control">
{% for author in author_list %}
<option value="{{ author.pk }}">{{ author.name }}</option>
{% endfor %} </select>
</div>
<input type="submit" class="btn btn-default">
</form>
</div>
</div>
</div>
</body>
</html>
models.py;
from django.db import models # Create your models here. #作者表;
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField() #出版社;
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField() #书籍表;
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
publishDate = models.DateField()
price = models.DecimalField(max_digits=5,decimal_places=2)#999.99
#与Publish表建立"一对多"的关系,外键字段建立在多的一方;
publish = models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
#与Author表建立多对多的关系,ManyToManyField可以建立两个模型中的任意一个,自动创建第三张表表;
authors = models.ManyToManyField(to="Author",)
第六模块:WEB框架开发 第1章·Django框架开发50~87的更多相关文章
- 第六模块:WEB框架开发 第1章·Django框架开发88~128
88-Ajax简介 89-Ajax的简单实现 90-基于Ajax的传递数据 91-基于Ajax的登录验证 92-基于Form表单的文件上传 93-请求头之contentType 94-Ajax传递js ...
- 第六模块:WEB框架开发 第1章·Django框架开发1~50
01-Django基础介绍 02-Web应用程序1 03-Web应用程序2 04-http请求协议1 05-http请求协议2 06-http协议之响应协议 07-wsgire模块1 08-wsgir ...
- 第四模块:网络编程进阶&数据库开发 第2章·MySQL数据库开发
01-MySQL开篇 02-MySQL简单介绍 03-不同平台下安装MySQL 04-Windows平台MySQL密码设置与破解 05-Linux平台MySQL密码设置与破解 06-Mac平台MySQ ...
- Python学习笔记_04:Django框架简介
目录 1 什么是Django? 2 Django框架的开发环境搭建 3 Django操作MySql数据库简介 4 功能强大的Django管理工具应用 1 什么是Django? Django是应用于We ...
- python 之 Django框架(服务器程序和应用程序、基础必备三件套及相关配置)
第十二章 Django框架 12.1 服务器程序和应用程序 服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理.应用程序则负责具体的逻辑处理.为了方便应用程序的开发, ...
- python主流框架简介和Django框架的使用
目录 一.手撸简易web框架 二.动静态网页 1. 静态网页 2. 动态网页 三.jinja2模板语法 1. jinja2的作用 四.python主流web框架 1. django 3. tornad ...
- 分布式队列celery 异步----Django框架中的使用
仅仅是个人学习的过程,发现有问题欢迎留言 一.celery 介绍 celery是一种功能完备的即插即用的任务对列 celery适用异步处理问题,比如上传邮件.上传文件.图像处理等比较耗时的事情 异步执 ...
- MySQL在Django框架下的基本操作(MySQL在Linux下配置)
[原]本文根据实际操作主要介绍了Django框架下MySQL的一些常用操作,核心内容如下: ------------------------------------------------------ ...
- Django框架数据库模型
博主最近开始优化之前的API接口自动化框架,这次打算使用django框架来完成 # -*- coding: utf-8 -*- from __future__ import unicode_liter ...
随机推荐
- jpa的修改更新操作
***指定id的保存就等于修改!!! save 指定id直接调用save()
- 用Java+xml配置方式实现Spring数据事务(编程式事务)
一.用Java配置的方式 1.实体类: Role public class Role { private int id; private String roleName; private String ...
- 【题解】洛谷P2023 [AHOI2009] 维护序列(线段树)
洛谷P2023:https://www.luogu.org/problemnew/show/P2023 思路 需要2个Lazy-Tag 一个表示加的 一个表示乘的 需要先计算乘法 再计算加法 来自你谷 ...
- ARM v7-A 系列CPU的MMU隐射分析
ARM v7-A 系列CPU的MMU隐射分析 摘要:ARM v7-A系列的CPU加入了很多扩展,如多核处理器扩展.大物理地址扩展.TrustZone扩展.虚拟化扩展.若支持大的物理地址,则必须支持多核 ...
- LeetCode28.实现strStr() JavaScript
实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始).如果不存在,则返 ...
- javascript入门教程 (1)
对于刚刚接触前端开发或者刚开始学习javascript的同学来说,js能用来做些什么,它是如何诞生的,它的组成结构是怎么的,在这些问题上可能都只有一些模糊的概念, js的入门篇 就是希望可以从0开始深 ...
- easy-im:一款基于netty的即时通讯系统
介绍 easy-im是面向开发者的一款轻量级.开箱即用的即时通讯系统,帮助开发者快速搭建消息推送等功能. 基于easy-im,你可以快速实现以下功能: + 聊天软件 + IoT消息推送 基本用法 项目 ...
- day 03 --Haproxy 增加, 删除,查询
key 知识点:函数的定义, 函数的递归调用, flag 标志位的使用,eval() 函数 #!C:\Program Files\Python35\bin # -*- conding:utf-8 -* ...
- uva_11806_Cheerleaders
In most professional sporting events, cheerleaders play a major role in entertaining the spectators. ...
- 复习宝典之Redis
查看更多宝典,请点击<金三银四,你的专属面试宝典> 第八章:Redis Redis是一个key-value的nosql数据库.先存到内存中,会根据一定的策略持久化到磁盘,即使断电也不会丢失 ...