• 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的更多相关文章

  1. 第六模块:WEB框架开发 第1章·Django框架开发88~128

    88-Ajax简介 89-Ajax的简单实现 90-基于Ajax的传递数据 91-基于Ajax的登录验证 92-基于Form表单的文件上传 93-请求头之contentType 94-Ajax传递js ...

  2. 第六模块: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 ...

  3. 第四模块:网络编程进阶&数据库开发 第2章·MySQL数据库开发

    01-MySQL开篇 02-MySQL简单介绍 03-不同平台下安装MySQL 04-Windows平台MySQL密码设置与破解 05-Linux平台MySQL密码设置与破解 06-Mac平台MySQ ...

  4. Python学习笔记_04:Django框架简介

    目录 1 什么是Django? 2 Django框架的开发环境搭建 3 Django操作MySql数据库简介 4 功能强大的Django管理工具应用 1 什么是Django? Django是应用于We ...

  5. python 之 Django框架(服务器程序和应用程序、基础必备三件套及相关配置)

    第十二章 Django框架 12.1 服务器程序和应用程序 服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理.应用程序则负责具体的逻辑处理.为了方便应用程序的开发, ...

  6. python主流框架简介和Django框架的使用

    目录 一.手撸简易web框架 二.动静态网页 1. 静态网页 2. 动态网页 三.jinja2模板语法 1. jinja2的作用 四.python主流web框架 1. django 3. tornad ...

  7. 分布式队列celery 异步----Django框架中的使用

    仅仅是个人学习的过程,发现有问题欢迎留言 一.celery 介绍 celery是一种功能完备的即插即用的任务对列 celery适用异步处理问题,比如上传邮件.上传文件.图像处理等比较耗时的事情 异步执 ...

  8. MySQL在Django框架下的基本操作(MySQL在Linux下配置)

    [原]本文根据实际操作主要介绍了Django框架下MySQL的一些常用操作,核心内容如下: ------------------------------------------------------ ...

  9. Django框架数据库模型

    博主最近开始优化之前的API接口自动化框架,这次打算使用django框架来完成 # -*- coding: utf-8 -*- from __future__ import unicode_liter ...

随机推荐

  1. 记录 iOS 各种跳转到系统应用

    MARK ----拨打电话 NSString* phoneVersion = [[UIDevice currentDevice] systemVersion]; if (phoneVersion.fl ...

  2. 简单使用Spring Boot+JpaRepository+hibernate搭建项目

    sql: -- -------------------------------------------------------- -- 主机: 127.0.0.1 -- 服务器版本: 10.3.9-M ...

  3. EF Core如何输出日志到Visual Studio的输出窗口

    我们在使用EF Core的时候,很多时候需要在Visual Studio的输出窗口中知道EF Core在后台生成的SQL语句是什么,这个需求可以通过自定义EF Core的ILoggerFactory和 ...

  4. java web中对json的使用

    一.在Java Web的开发过程中,如果希望调用Java对象转化成JSON对象等操作.则需要引入以下jar包,不然运行时则报错. 1.commons-beanutils.jar 2.commons-c ...

  5. 选择排序_c++

    选择排序_c++ GitHub 文解 选择排序的核心思想是对于 N 个元素进行排序时,对其进行 K = (N - 1) 次排序,每次排序从后(N + 1 - K)个数值中选择最小的元素与以 (K - ...

  6. 利用MyFlash闪回丢失数据(续)

          last night,i've tested flashback by MyFlash tool,but failed,now let's do some other test with ...

  7. CentOS 6.8安装Ceph

    机器规划 IP 主机名 角色 10.101.0.1 ceph01 mon admin mds 10.101.0.2 ceph02 ods 10.101.0.3 ceph03 ods 10.101.0. ...

  8. Web移动端商城 移动端商城手机网站html整套模板,web移动商城仿app手机模板下载

    --Web移动端商城移动端商城手机网站html整套模板,web移动商城仿app手机模板下载.原生的js和jquery-1.6.2.min.js,页面才有html5自适应.包括首页(轮播,导航).兼职( ...

  9. window安装ubuntu系统

  10. 一条sql 执行查询列表 返回分页数据以及总数 totalCount

    SELECT ID,Name,Age,Addr,Tel,COUNT(1) OVER() AS totalFROM dbo.Student WHERE Age>22 ORDER BY id DES ...