django模型层2 多表操作

1.多表操作:

  1.创建模型:

实例:我们来假定下面这些概念,字段和关系

作者模型:一个作者有姓名和年龄。

作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)

出版商模型:出版商有名称,所在城市以及email。

书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。

模型建立如下:

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()

    # 与AuthorDetail建立一对一的关系
    authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)

class AuthorDetail(models.Model):

    nid = models.AutoField(primary_key=True)
    birthday=models.DateField()
    telephone=models.BigIntegerField()
    addr=models.CharField( max_length=64)

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建立一对多的关系,外键字段建立在多的一方
    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
    authors=models.ManyToManyField(to=‘Author‘,)

注意事项:

  • 表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称  
  •  id 字段是自动添加的
  • 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
  • 这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
  • 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
  • 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。

  2.添加数据库

操作前先简单的录入一些数据:

publish表:

author表:

authordetail表:

一对多


1

2

3

4

5

6

方式1:

   publish_obj=Publish.objects.get(nid=1)

   book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish=publish_obj)

 

方式2:

   book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish_id=1)  

多对多

# 当前生成的书籍对象
    book_obj=Book.objects.create(title="追风筝的人",price=200,publishDate="2012-11-12",publish_id=1)
    # 为书籍绑定的做作者对象
    yuan=Author.objects.filter(name="yuan").first() # 在Author表中主键为2的纪录
    egon=Author.objects.filter(name="alex").first() # 在Author表中主键为1的纪录

    # 绑定多对多关系,即向关系表book_authors中添加纪录
    book_obj.authors.add(yuan,egon)    #  将某些特定的 model 对象添加到被关联对象集合中。   =======    book_obj.authors.add(*[])

多对多关系其它常用API:

将某个特定的对象从关联的对象集合中去除:

  book_obj.authours.remove()

清空被关联的对象集合:

  book_obj.authors.clrar()

先清空,在设置:

  book_obj.authors.set()

详情请点我!!!

所有的查询:

def select(request):    ################基于对象的跨表查询##############    # 1.1对多    # 1.查询linex这本书出版社的名字和邮箱

    # book = Book.objects.filter(title="linex").first()    # # pub_obj = Publish.objects.first(nid=book.publish_id).first()    # # print(pub_obj.name)    # print(book.publish.name)    # print(book.publish.email)    # 2    # 查询人民教育出版社出版的所有的书籍的名称    # pub_obj=Publish.objects.get(name="人民教育出版社")    # print(pub_obj.book_set.all().values("title"))

    ####### 多对多 ##########    # 查询linex这本书籍的作者的年龄    # book=Book.objects.filter(title="linex").first()    # ret=book.authors.all().values("age")    # print(ret)    # #查询alex出版过的所有的书籍名称    # alex=Author.objects.filter(name="alex").first()    # print(alex.book_set.all())    # alex=Author.objects.filter(name="alex").first()    # print(alex.book_set.all())

    ####### 一对一 ##########    # 查询alex的手机号    # alex=Author.objects.filter(name="alex").first()    # print(alex.ad.tel )    # alex=Author.objects.filter(name="alex").first()    # print(alex.ad.tel)    # # 查询手机号为110的作者的名字    # ad=AuthorDetail.objects.filter(tel=110).first()    # print(ad.author.name)

    #########基于双下划线的跨表查询(基于join实现的)#########    # 1    # 查询linex这本书出版社的名字    # ret=Book.objects.filter(title="linex").values("publish__name")    # print(ret)    # pub_obj=Publish.objects.filter(book__title=‘linex‘).values("name")    # print(pub_obj)    # ret=Book.objects.filter(title="linex").values("publish__name")    # print(ret)    # ret=Publish.objects.filter(book__title="linex").values("name")    # print(ret)    # 2    # 查询人民教育出版社出版的所有的书籍的名称    # ret=Book.objects.filter(publish__name="人民教育出版社").values("title")    # print(ret)    # ret=Publish.objects.filter(name="人民教育出版社").values("book__title")    # print(ret)    # 3 查询python这本书籍的作者的年龄    # ret=Book.objects.filter(title="linex").values("authors__age")    # print(ret)    # ret=Author.objects.filter(book__title="linex").values("age")    # print(ret)    # ret=Book.objects.filter(title="linex").values("authors__age")    # print(ret)    # ret=Author.objects.filter(book__title="linex").values("age")    # print(ret)    #    # 4 查询alex出版过的所有的书籍名称    # ret=Book.objects.filter(authors__name="alex").values("title")    # print(ret)    # ret=Author.objects.filter(name="alex").values("book__title")    # print(ret)    # 5 查询alex的手机号    # ret=Author.objects.filter(name="alex").values("ad__tel")    # print(ret)    # ret=AuthorDetail.objects.filter(author__name="alex").values("tel")    # print(ret)    # 6 查询手机号为110的作者的名字    # ret=Author.objects.filter(ad__tel=110).values("name")    # print(ret)    # ret=AuthorDetail.objects.filter(tel=110).values("author__name")    # print(ret)    # 查询人民教育出版社出版过的所有书籍的名字以及作者的姓名    # ret=Publish.objects.filter(name="人民教育出版社").values("book__title","book__authors__name")    # print(ret)    # ret=Publish.objects.filter(name="人民教育出版社").values("book__title","book__authors__name")    # print(ret)    # ret=Book.objects.filter(publish__name="人民教育出版社").values("title","authors__name")    # print(ret)    # ret=Book.objects.filter(publish__name="人民教育出版社").values("title","authors__name")    # print(ret)    # 手机号以110开头的作者出版过的所有书籍名称以及出版社名称    # ret=AuthorDetail.objects.filter(tel__startswith=110).values("author__book__title","author__book__publish__name")    # print(ret)    # ret=AuthorDetail.objects.filter(tel=110).values("author__book__title","author__book__publish__name")    # print(ret)    # ret=Book.objects.filter(authors__ad__tel=110).values("title","publish__name")    # print(ret)    # ret=Author.objects.filter(ad__tel=110).values("book__title","book__publish__name")    # print(ret)    ################ 聚合 分组 ################    from django.db.models import Avg,Max,Min,Count    # 查询所有书籍的平均价格    # ret=Book.objects.all().aggregate(Avg("price"))    # print(ret)    # # 查询所有书籍的个数    # ret=Book.objects.all().aggregate(c=Count(1))    # print(ret)    # 查询书籍表每一个出版社id以及对应的书籍个数    # ret=Book.objects.annotate(c=Count(1)).values("publish_id","c")    # print(ret)    # 查询每一个部门的名称以及对应员工的平均薪水    # ret=Emp.objects.annotate(c=Avg("salary")).values("dep","c")    # print(ret)    # ret=Emp.objects.values("dep").annotate(c=Avg("salary"))    # print(ret)    # 查询每一个省份的名称以及对应的员工最大年龄    # ret= Emp.objects.values("pro").annotate(c=Max("age"))    # print(ret)    # 跨表分组查询    # 查询每一个出版社的名称以及对应的书籍平均价格    # ret=Publish.objects.annotate(c=Avg("book__price")).values("c","name")    # print(ret)    # 查询每一个作者的名字以及出版的书籍的最高价格    # ret=Author.objects.annotate(M=Max("book__price")).values(‘M‘,"name")    # print(ret)    # 查询每一个书籍的名称以及对应的作者的个数    # ret=Book.objects.annotate(a=Count("authors")).values("title","a")    # print(ret)    # 4    # 查询作者数不止一个的书籍名称以及作者个数    # ret=Book.objects.annotate(c=Count("authors__name")).filter(c__gt=1).values("title","c")    # print(ret)    # ret=Book.objects.annotate(c=Count("authors__name")).filter(c__gt=1).values("title","c")    # print(ret)    # 5 根据一本图书作者数量的多少对查询集 QuerySet进行排序    # ret=Book.objects.annotate(c=Count("authors__name")).order_by("c")    # print(ret)    # 6 统计每一本以py开头的书籍的名称以及作者个数    # ret=Book.objects.filter(title__startswith="li").annotate(c=Count("authors__name"))    # print(ret)    # ret=Book.objects.filter(title__startswith="li").annotate(c=Count("authors__name")).values("title","c")    # print(ret)    ################ F 与 Q ################    from django.db.models import F, Q    # # 查询评论数大于100的所有的书籍名称    # ret=Book.objects.filter(comment_count__gt=2000).values("title")    # print(ret)    # # 查询评论数大于2倍点赞数的所有的书籍名称    # ret=Book.objects.filter(comment_count__gt=F("poll_count")*2)    # print(ret)    # 给每一本书籍的价格提升100    ret=Book.objects.all().update(price=100+F("price"))    print(ret)

    return HttpResponse("ok")

  

原文地址:https://www.cnblogs.com/wqzn/p/9858753.html

时间: 2024-10-01 05:22:06

django模型层2 多表操作的相关文章

Django模型层之单表操作

Django模型层之单表操作 一 .ORM简介 我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(如增.删.改.查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql.oracle.Microsoft SQL Server等. 如果应用程序需要操作数据(比如将用户注册信息永久存放起来),那么我们需要在应用程序中编写原生sql语句,然后使用pymysql模块远程操作mysql数据库,详见图一^①^ 但是直接编写原生sql语句会存在两方面的问题,严

Django基础五之django模型层(一)单表操作

目录 一 ORM简介 二 单表操作 一.创建表 创建模型 2 更多字段和参数 3 settings配置 4.自定义字段(了解) 二.添加表纪录 方式1 方式2(用的多) 方式3:批量插入 三.查询表纪录 查询API(都是重点) 基于双下划线的模糊查询 四.删除表纪录 五.修改表纪录 三 章节作业 1 图书管理系统 2 查询操作练习 四 xxx 本节目录 一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,

Django基础五之django模型层(二)多表操作

目录 一 创建模型 关于db_column和verbose_name 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询(基于join实现的) 进阶练习(连续跨表) 五 聚合查询.分组查询.F查询和Q查询 查询练习 F查询与Q查询 F查询 Q查询 六 ORM执行原生sql语句(了解) 执行原生查询 直接执行自定义SQL 七 Python脚本中调用Django环境(django外部脚本使用models) 八 补充多个app配置models 本节目录 一 创建模型 表和表之间的关系

web框架开发-Django模型层(2)-多表操作

很重要,都是精华 多表关系模型 一对一 一旦确定表关系是一对一,在两张表中的任意一张表中建立关联字段+Unique 一对多 一旦确定表关系是一对多,创建关联字段在多的表中 多对多 一旦确定表关系是多对多,创建第三章关系表 ORM生成关系表模型 假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系(one-to-one) 出版商模型:出版商有名称,所在城市以及email. 书

Django模型层之多表操作

作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系(one-to-one) 出版商模型:出版商有名称,所在城市以及email. 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many). 具体的模型如下:(models.

Django模型层(多表操作)

创建模型 (一)多表查询 一对一:models.OneToOneField(to_field='id',to='Authordatil') 一对多:(外键设置唯一性) models.ForeignKey(to='Publish',to_field='id') 多对多:自动生成第三张表 models.ManyToManyField(to='Author') (二)创建表模型 作者与详情 ( 一对一 ) 书与作者( 多对多 ) 出版社与书(一对多 ) 出版社:id name add email 书:

9.17 模型层 ORM 单表操作

1 创建模型 创建名为book的app,在book下的models.py中创建模型: from django.db import models # Create your models here. class Book(models.Model): id=models.AutoField(primary_key=True) title=models.CharField(max_length=32) state=models.BooleanField() pub_date=models.DateF

Python Django 模型层

一 单表操作 create_time = models.DateField() # 不指定auto_now或auto_now_add时,需要自己传参数 关键性的参数: 1.auto_now:每次操作数据 都会自动刷新当前操作的时间 2.auto_now_add:在创建数据的时候 会自动将创建时间记录下来 后续的修改不会影响该字段 二 测试脚本文件使用 django中 你可以写一个单独测试某一个py文件的测试脚本 不需要再频繁的走web请求 1.脚本测试文件必须的代码 import os impo

Django模型层之更多操作

Django模型层之更多操作 一 .ORM字段 1.1 常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型,范围在-2147483648 to 2147483647. CharField 字符类型,必须提供max_length参数, max_length表示字符长度. DateField 日期字段,日期格式 YYYY-MM-DD,相当于Python中的d