• 多表操作


    
    
     一对多新增数据
         添加一本北京出版社出版的书
         第一种方式
         ret=Book.objects.create(name='红楼梦',price=34.5,publish_id=1)
         print(ret.name)
    
         第二种方式,存对象publish=出版社的对象,存到数据库,是一个id
         publish=Publish.objects.get(id=1)
         pk是主键,通过主键查找
         publish=Publish.objects.get(pk=1)
         publish = Publish.objects.filter(pk=2).first()
         ret = Book.objects.create(name='西游记', price=34.5, publish=publish)
         print(ret.name)
    
         一对多修改数据
         book=Book.objects.get(pk=1)
          book.publish=出版社对象
         book.publish_id=2
         book.save()
    
         方式二
         book=Book.objects.filter(pk=1).update(publish=出版社对象)??
         book=Book.objects.filter(pk=1).update(publish_id=1)
         多对多新增
    
         为红楼梦这本书新增一个叫lqz,egon的作者
         lqz=Author.objects.filter(name='lqz').first()
         egon=Author.objects.filter(name='egon').first()
         book=Book.objects.filter(name='红楼梦').first()
    
          add 添加多个对象
         book.authors.add(lqz,egon)
    
         add添加作者id
         book.authors.add(1,2)
    
        删除 remove,可以传对象,可以传id,可以传多个,不要混着用
         book.authors.remove(lqz)
         book.authors.remove(2)
         book.authors.remove(1,2)
    
         clear清空所有
         book.authors.clear()
    
         set,先清空,在新增,要传一个列表,列表内可以是, id,也可以是对象
         book.authors.set([lqz,])
    
         ********这样不行,因为它打散了传过去了,相当于book.authors.set(lqz)
         book.authors.set(*[lqz,])
    
    
         lqz=Author.objects.filter(name='lqz')
         print(type(lqz))
        from  django.db.models.query import QuerySet
     ***************************基于对象的跨表查询
        '''
        一对一
        正向   author---关联字段在author--->authordetail   ------>  按字段
        反向   authordetail------关联字段在author--->author  -----> 按表名小写
        
        '''
         查询lqz作者的手机号   正向查询
         author=Author.objects.filter(name='lqz').first()
          author.authordetail 就是作者详情的对象
         authordetail=author.authordetail
         print(authordetail.phone)     查询地址是 :山东 的作者名字   反向查询     authordetail=AuthorDetail.objects.filter(addr='山东').first()      authordetail.author  这是作者对象     author=authordetail.author     print(author.name)
    
        一对多
        '''
        一对多
        正向   book---关联字段在book--->publish   ------>  按字段
        反向   publish------关联字段在book--->book  -----> 按表名小写_set.all()
        '''
         正向 查询红楼梦这本书的出版社邮箱
         book=Book.objects.filter(name='红楼梦').first()
          book.publish  就是出版社对象
         pulish=book.publish
         print(pulish.email)
         反向  查询地址是北京 的出版社出版的图书
         publish=Publish.objects.filter(addr='北京').first()
          publish.book_set.all()  拿出所有的图书
         books=publish.book_set.all()
          统计一下条数
         books=publish.book_set.all().count()
         print(books)
    
        '''
        多对多
        正向   book---关联字段在book--->author   ------>  按字段.all()
        反向   author------关联字段在book--->book  -----> 按表名小写_set.all()
        '''
        查询红楼梦这本书所有的作者
         book=Book.objects.filter(name='红楼梦').first()
         book.authors.all()  是所有的作者,是一个queryset对象,可以继续点
         print(book.authors.all())
    
         查询lqz写的所有书
         lqz=Author.objects.filter(name='lqz').first()
         books=lqz.book_set.all()
         print(books)
    
         连续跨表
         查询红楼梦这本书所有的作者的手机号
         book=Book.objects.filter(name='红楼梦').first()
         authors=book.authors.all()
         for author in authors:
             authordetail=author.authordetail
             print(authordetail.phone)
    
    
         ****************************基于对象的查询---是子查询也就是多次查询
         ***************基于双下划线的查询*****
         一对一
         查询lqz作者的手机号   正向查询  跨表的话,按字段
         以author表作为基表
         ret=Author.objects.filter(name='lqz').values('authordetail__phone')
         print(ret)
         以authordetail作为基表 反向查询,按表名小写  跨表的话,用表名小写
         ret=AuthorDetail.objects.filter(author__name='lqz').values('phone')
         print(ret)
         查询lqz这个作者的性别和手机号
         正向
         ret=Author.objects.filter(name='lqz').values('sex','authordetail__phone')
         print(ret)
         查询手机号是13888888的作者性别
         ret=Author.objects.filter(authordetail__phone='13888888').values('sex')
         print(ret)
         ret=AuthorDetail.objects.filter(phone='13888888').values('author__sex')
         print(ret)
    
    
    
      1 创建多表模型(详情见代码)    
    用了OneToOneField和ForeignKey,模型表的字段,后面会自定加_id
    ManyToManyField会自动创建第三张表
    一对一的关系:OneToOneField
    一对多的关系:ForeignKey
    多对多的关系:ManyToManyField

    2 添加表记录
      1 一对多新增
         -两种方式:
          -publish=对象
          -publish_id=id
    2 一对多删除:同单表删除
    3 一对多修改:两种方式,可以传对象,可以传id
    4 一对一跟一对多一样
    5 多对多:
        -add ----->可以传对象,可以传id,可以传多个
        -remove ----->可以传对象,可以传id,可以传多个
        -clear ---->没有参数
        -set ----->跟上面不一样,必须传列表,列表里面可以是对象,可以是id
    
    
    3 基于对象的跨表查询    
      1 一对一
        正向:正向查询按字段
        反向:反向查询按表名小写
      2 一对多
        正向:正向查询按字段
        反向:反向按表名小写_set.all()
      3 多对多
        正向:正向查询按字段
        反向查询:反向按表名小写_set.all()
    4 基于双下划线的跨表查询    
        -连表查询
        -一对一双下划线查询
          -正向:按字段,跨表可以在filter,也可以在values中
          -反向:按表名小写,跨表可以在filter,也可以在values中
    
    
    id如果不写,会自动生成,名字叫nid,并且自增

    可以用ForeignKey,但是得设置唯一性约束,会报警告,不建议用,建议用OneToOneField
    authordetail=models.ForeignKey(unique=True)
    to='AuthorDetail' 加引号,这个表能找到就可以,不用引号,类必须在上面定义
    
    
    用了OneToOneField和ForeignKey,模型表的字段,后面会自定加_id 
    ManyToManyField会自动创建第三张表
    一对一的关系:OneToOneField
    一对多的关系:ForeignKey
    多对多的关系:ManyToManyField
    
    
    
    
  • 相关阅读:
    flask强大的第三方组件之falsk-sqlalchemy
    flask 外键关系和多对多查询
    flask sqlalchemy 单表查询
    functools模块
    面试题
    ansible git
    python 操作 表格
    matplotlib
    node,npm,webpack,vue-cli模块化编程安装流程
    Webpack
  • 原文地址:https://www.cnblogs.com/zhouhao123/p/9954753.html
Copyright © 2020-2023  润新知