• 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. .ne 基础(2)

    类是一种抽象 抽象的概念,具体的实例. 现实是先有对象,再抽象成类,再用类来创建实例 构造方法 (1)如果写好了类,不写构造方法,系统会默认一个无参的构造方法 (2) 如果手动添加了一个 构造方法,就 ...

  2. 【转】Java中关于WeakReference和WeakHashMap的理解

    新美大的10月11日的笔试中有一道选择题,让选择函数返回结果,代码如下: private static String test(){ String a = new String("a&quo ...

  3. 面试准备——(二)专业知识(4)C/C++语言

    1. 预处理 断言 assert的功能,assert(statement),如果statement为真则程序继续执行,为假则整个程序中断退出 3. #define [ #ifndef DISKSIM_ ...

  4. 面试准备——(二)专业知识(1)Linux

    面试的问题: 腾讯: 1. 查看进程的命令 美团: 1. 常用的命令——美团/滴滴 2. 如何在性能测试的时候查看进程 3. kill -9/-15区别 滴滴: 1.如何找到一个特定文件 2. 如何替 ...

  5. GIS中的空间参考

    GIS一般都是研究的基于地球的某个区域,例如一个国家.省或市的情况,既然地球上都有经纬度来标识,那么直接用经纬度来标识物体的位置不可以吗?但如果应用不一样,在实际中选择的空间参考系也是不一样的.例如我 ...

  6. CSU - 2031 Barareh on Fire (两层bfs)

    传送门: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2031 Description The Barareh village is on f ...

  7. 使用BSRR和BRR寄存器直接操作STM32的I/O端口

    STM32的每个GPIO端口都有两个特别的寄存器,GPIOx_BSRR和GPIOx_BRR寄存器,通过这两个寄存器可以直接对对应的GPIOx端口置'1'或置'0'. GPIOx_BSRR的高16位中每 ...

  8. 打印iframe某区域

    <a href="#" onClick="parent.iframe名字.focus();window.print();">打印</a>

  9. 课时25.a标签基本使用(掌握)

    什么是a标签? 我们打开百度或者淘宝网页,观察任何一个超链接都会发现它有如下特质: 有下划线 移上去有小手指 可以点击 a标签的作用:就是用于控制页面与页面之间跳转的 a标签的格式:<a hre ...

  10. UE4 Navmesh 室内导航设置

    我用的UE版本是4.14.1   系统:win10 64 前不久给样板房里面做了一个扫地机器人,导航设置让我头大了很久,度娘也没有用,最后在谷哥上有所感悟,现在给出本人的设置过程和解决方案. 一开始拖 ...