博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django 的 orm 查询
阅读量:5145 次
发布时间:2019-06-13

本文共 20805 字,大约阅读时间需要 69 分钟。

一.模型关系表    1. 一对一       Author-AuthorDetail       关联字段可以在任意表下,但必须唯一约束。(unique约束)       ad_id(unique约束)       ad = models.oneToOneField("AuthorDetail",null=True,on_delete=models.CASCADE)       相当于 authors = models.ForgeinKey(to="Author",on_delete=models.CASCADE,unique)    2. 一对多       publish-book       关联字段在“多”的表中       建立ForgeinKey 约束    3. 多对多       book-author       关系表       foreinkey book_id references Book(id)       foreinkey author_id references Author(id)       authors = models.ManyToManyField("Author") 二.多表查询    a.一定要知道mysql 语句    b.增删改查 =========================================================================================================================    1. 添加       create       添加记录的思路:考虑 三种关系表的特殊字段       Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1) #数据库级别       def add(request):          ======================绑定一对多关系===========================================          #一对多:(publish-book)             方式一:                Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1)             方式二:                pub_obj = Publish.objects.filter(name= "苹果出版社").first()                Book.objects.create(title="python",price=123,pub_date = "2012-11-12",publish=pub_obj)                python = Book.objects.filter(title="python").first()                python.publish #得到的是python这本书对应的出版社对象          ===================绑定多对多关系:无非是在第3张关系表中创建记录=====================          正向操作按字段,反向操作按表名小写          #多对多:(authors-book)             key:一定要找到多对多关联属性在哪张表下,如Book下的authors,先找到book对象,再用该书籍对象                点关联字段             1.给python这本书绑定两个作者:alex egon                python = Book.objects.filter(title="python").first()                alex = Author.objects.filter(name="alex").first()                egon = Author.objects.filter(name="egon").first()                python.authors.add(alex,egon)                python.authors.add(1,2) #1,2分别为alex,egon的主键                python.authors.add(*[1,2,3,4,5]) #打散传                python.authors.remove(alex,egon)                python.authors.clear() #解除所有绑定                python.authors.set([1,]) #先清空,在赋值操作             2. 给alex作者绑定两本书籍 python和linux                alex = Author.objects.filter(name="alex").first()                python= Book.objects.filter(title="python").first()                linux= Book.objects.filter(title="linux").first()                alex.book_set.add(alex,linux) ==========================================================================================================================    2.查询       def queryset(request):          ===============================基于对象的跨表查询================================             基于对象的跨表查询:(sql语句 子查询:以上一次的查询结果作为下一次的查询条件)             1.一对多:                   正向查询按字段publish    linux.publish             Book----------------------------------------------Publish                   反向查询按表名小写_set.all()                1.查询linux这本书籍出版社的邮箱                   linux = Book.objects.filter(title="linux").first()                   print(linux.publish.emial)                2.查询苹果出版社出版的所有书籍                   p1 = Publish.objects.filter(name="苹果出版社").first()                   queryset = p1.book_set.all()             2. 多对多:                      正向查询按字段authors   book_obj.authors.all()                Book---------------------------------------------------Author                      反向查询按表名小写_set().all()                1.查询linux这本书所有作者                   linux= Book.objects.filter(title="linux").first()                   queryset = linux.authors.all()                2.查询作者alex出版过的所有书籍                   alex = Author.objects.filter(name="alex").first()                   queryset = alex.book_set.all()             3. 一对一:                      正向查询按字段ad,     author_obj.ad                Author--------------------------------------------AuthorDetail                      反向查询按表名小写   Authordetail_obj.author                1.查询alex手机号                   alex= Author.objects.filter(name="alex").first()                   alex.ad.telphone                2.查询手机号为123的作者                   ad_obj = AuthorDetail.objects.filter(telphone=123).first()                   print(ad_obj.author.name)          =================================基于双下滑线的跨表查询(join查询)=======================================             把多张表合成一张表,按单表查。             key: 通知orm引擎,进行跨表,正向查询按表名,反向查询按表名小写             1.一对多                1.查询linux这本书籍出版社的邮箱                   sql :                      select email from book inner join publish on book.publish_id = publish.id where book.title='linux'                   orm :(values 显示查询字段)                      #方式一                         queryset = Book.objects.filter(title="linux").values("publish__email")                      #方式二                         queryset = Publish.objects.filter(book__title = "linux").value("email")             2.多对多                1.查询linux这本书的所有作者名字                   sql:                      select author.name from book left join book2authors on book.id = book2authors.book_id                                     left join author on author.id = book2authors.author_id                                     where book.title="linux"                   orm:                      方式一:                         queryset = Book.objects.filter(title="linux").values("authors__name")                         left join 显示左边表中所有的数据                         inner join如果基表没有数据就不显示第二个表中的那部分数据                      方式二:                         queryset = Author.objects.filter(book__title="linux").values('name')             3. 一多一                1.查询alex手机号                   方式一:                      queryset = Author.objects.filter(name="alex").values("ad__telphone")                   方式二:                      queryset = AuthorDetail.objects.filter(author__name="alex").values("telphone")             4.连续跨表查询                1.查询人民出版社出版过的所有书籍名称以及作者名字                   Publish.objects.filter(name="人民出版社").values("book__name","book__authors__name")                   Book.objects.filter(publish__name="人民出版社").values("name","authors__name")                2.手机号以151开头的作者出版过的所有书籍名称以及所有出版社名称                   Author.objects.filter(ad__telphone__startswith=151).values("book__name","book__publish__name")          ================================聚合和分组查询============================================          1.聚合(aggregate 只对一组进行统计)             from django.db.models import Avg,Count,Max,Min             1.计算所有图书的平均价格                Book.objects.all().aggregate(avg_price=Avg("price"))             2. 计算所有图书的最高价和最低价                Book.objects.all().aggregate(min_price=Min("price"),max_price=Max('price'))          2.分组查询 (annotate 对多组数据进行统计)             1.单表分组:                emp                id  name salary dep    province                1   alex 20000  销售部  山东                2   egon 30000  人事部  河北                3   wang 40000  人事部  山东                查询 : 每个部门的名称以及员工人数                sql:                   select dep,Count(*) from emp group by dep;                   select dep,Avg(salary) from emp group by dep;                orm:                   按哪个字段group by 就 values 哪个字段,用annotate 统计                   1.查询每个部门的名字                   queryset = Emp.objects.values("dep").annotate(c=Count("*"))                   2.查询每个省份的平均薪水                   queryset= Emp.objects.values("province").annotate(avg_salary=Avg("salary"))             2.多表分组:(多张关联表)                key:多张表join起来,再按单表查                1.查询每个出版社的名称以及出版过书籍的平均价格                   sql:                      select publish.name,Avg(book.price) from publish left join book on publish.id = book.publish_id                      group by publish.id,publish.name                   orm:                      方式一:                         queryset = Publish.objects.values("name","id").annotate(avg_price =avg("book__price"))                      方式二:                         queryset = Publish.objects.all().annotate(avg_price =avg("book__price"))                 2.查询每一个作者的名字以及出版书籍的个数                    方式一:                       queryset = Author.objects.values("name").annotate(book_num=Count("book"))                    方式二:                       queryset = Author.objects.annotate(book_num=Count("book")).values("book_num","name")                 3.查询每本书籍名称以及作者个数                    queryset = Book.objects.annotate(c=Count("authors")).values("title",c)                 4.查询作者个数大于1的书籍名称和作者个数                    sql:                       select book.tilte,Count(author.id) as c from book left join book2authors on book.id = book2authors.book_id                                      left join Author on book2authors.author_id                                      group by book.id                                      having c>1                    orm:                       queryset = Book.objects.annotate(c=Count("authors")).filter(c__gt=1).values("title","c")                                                               (相当于having)                 5.查询书籍名称包含“h"的书籍名称和作者个数                    Book.objects.filter(title__icontains='h').annonate(c=Count('authors')).values("title",c)                              (相当于where)       ====================================F查询和Q查询===================================================       from django.db.models import F,Q,Avg       1.F查询          1.查询评论数大于100的文章             Article.objects.filter(comment_num__gt=100)          2.查询评论数大于点赞数的文章             Article.objects.filter(comment_num__gt=F(poll_num))          3.查询评论数大于100的所有文章              queryset = Article.objects.filter(comment_num__gt=F("poll_num")*2)           4.将所有书籍的价格提高一百元              Book.objects.update(price=F("price")+100)       2.Q查询 (|或  &且  ~非)          1.查询价格大于200或名称以"p"开头的书籍             queryset = Book.objects.all().filter(Q(price__gt=200)|Q(title__startswith="p")          2.查询价格大于300或出版日期(不是)为2019年一月份的书籍             queryset= Book.objects.filter(Q(price__gt=300)|~Q(Q(pub_date_year=2019)&Q(pub_date_month=1)))
一.模型关系表    1. 一对一        Author-AuthorDetail        关联字段可以在任意表下,但必须唯一约束。(unique约束)        ad_id(unique约束)        ad = models.oneToOneField("AuthorDetail",null=True,on_delete=models.CASCADE)        相当于 authors = models.ForgeinKey(to="Author",on_delete=models.CASCADE,unique)             2. 一对多        publish-book                关联字段在“多”的表中        建立ForgeinKey 约束    3. 多对多        book-author        关系表        foreinkey book_id references Book(id)        foreinkey author_id references Author(id)        authors = models.ManyToManyField("Author")二.多表查询    a.一定要知道mysql 语句    b.增删改查=========================================================================================================================    1. 添加        create        添加记录的思路:考虑 三种关系表的特殊字段        Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1) #数据库级别             def add(request):            ======================绑定一对多关系===========================================            #一对多:(publish-book)                方式一:                    Book.objects.create(title="python",price=123,pub_date="2012-12-12",publish_id=1)                方式二:                    pub_obj = Publish.objects.filter(name= "苹果出版社").first()                    Book.objects.create(title="python",price=123,pub_date = "2012-11-12",publish=pub_obj)                    python = Book.objects.filter(title="python").first()                     python.publish #得到的是python这本书对应的出版社对象                        ===================绑定多对多关系:无非是在第3张关系表中创建记录=====================            正向操作按字段,反向操作按表名小写                        #多对多:(authors-book)                key:一定要找到多对多关联属性在哪张表下,如Book下的authors,先找到book对象,再用该书籍对象                    点关联字段                1.给python这本书绑定两个作者:alex egon                    python = Book.objects.filter(title="python").first()                    alex = Author.objects.filter(name="alex").first()                    egon = Author.objects.filter(name="egon").first()                    python.authors.add(alex,egon)                    python.authors.add(1,2) #1,2分别为alex,egon的主键                    python.authors.add(*[1,2,3,4,5]) #打散传                    python.authors.remove(alex,egon)                     python.authors.clear() #解除所有绑定                    python.authors.set([1,]) #先清空,在赋值操作                2. 给alex作者绑定两本书籍 python和linux                    alex = Author.objects.filter(name="alex").first()                    python= Book.objects.filter(title="python").first()                    linux= Book.objects.filter(title="linux").first()                    alex.book_set.add(alex,linux)==========================================================================================================================        2.查询        def queryset(request):            ===============================基于对象的跨表查询================================                                基于对象的跨表查询:(sql语句 子查询:以上一次的查询结果作为下一次的查询条件)                1.一对多:                        正向查询按字段publish    linux.publish                Book----------------------------------------------Publish                        反向查询按表名小写_set.all()                    1.查询linux这本书籍出版社的邮箱                        linux = Book.objects.filter(title="linux").first()                        print(linux.publish.emial)                    2.查询苹果出版社出版的所有书籍                        p1 = Publish.objects.filter(name="苹果出版社").first()                        queryset = p1.book_set.all()                                2. 多对多:                            正向查询按字段authors   book_obj.authors.all()                    Book---------------------------------------------------Author                            反向查询按表名小写_set().all()                     1.查询linux这本书所有作者                        linux= Book.objects.filter(title="linux").first()                        queryset = linux.authors.all()                    2.查询作者alex出版过的所有书籍                        alex = Author.objects.filter(name="alex").first()                        queryset = alex.book_set.all()                3. 一对一:                            正向查询按字段ad,     author_obj.ad                    Author--------------------------------------------AuthorDetail                            反向查询按表名小写   Authordetail_obj.author                    1.查询alex手机号                        alex= Author.objects.filter(name="alex").first()                        alex.ad.telphone                    2.查询手机号为123的作者                        ad_obj = AuthorDetail.objects.filter(telphone=123).first()                        print(ad_obj.author.name)                            =================================基于双下滑线的跨表查询(join查询)=======================================                把多张表合成一张表,按单表查。                key: 通知orm引擎,进行跨表,正向查询按表名,反向查询按表名小写                1.一对多                    1.查询linux这本书籍出版社的邮箱                                            sql :                            select email from book inner join publish on book.publish_id = publish.id where book.title='linux'                        orm :(values 显示查询字段)                            #方式一                                queryset = Book.objects.filter(title="linux").values("publish__email")                            #方式二                                queryset = Publish.objects.filter(book__title = "linux").value("email")                2.多对多                    1.查询linux这本书的所有作者名字                        sql:                            select author.name from book left join book2authors on book.id = book2authors.book_id                                               left join author on author.id = book2authors.author_id                                               where book.title="linux"                        orm:                            方式一:                                queryset = Book.objects.filter(title="linux").values("authors__name")                                left join 显示左边表中所有的数据                                inner join如果基表没有数据就不显示第二个表中的那部分数据                            方式二:                                queryset = Author.objects.filter(book__title="linux").values('name')                3. 一多一                    1.查询alex手机号                        方式一:                            queryset = Author.objects.filter(name="alex").values("ad__telphone")                        方式二:                            queryset = AuthorDetail.objects.filter(author__name="alex").values("telphone")                4.连续跨表查询                    1.查询人民出版社出版过的所有书籍名称以及作者名字                        Publish.objects.filter(name="人民出版社").values("book__name","book__authors__name")                        Book.objects.filter(publish__name="人民出版社").values("name","authors__name")                    2.手机号以151开头的作者出版过的所有书籍名称以及所有出版社名称                        Author.objects.filter(ad__telphone__startswith=151).values("book__name","book__publish__name")            ================================聚合和分组查询============================================                        1.聚合(aggregate 只对一组进行统计)                from django.db.models import Avg,Count,Max,Min                1.计算所有图书的平均价格                    Book.objects.all().aggregate(avg_price=Avg("price"))                2. 计算所有图书的最高价和最低价                    Book.objects.all().aggregate(min_price=Min("price"),max_price=Max('price'))            2.分组查询 (annotate 对多组数据进行统计)                1.单表分组:                    emp                     id  name salary dep    province                    1   alex 20000  销售部  山东                    2   egon 30000  人事部  河北                    3   wang 40000  人事部  山东                    查询 : 每个部门的名称以及员工人数                    sql:                        select dep,Count(*) from emp group by dep;                        select dep,Avg(salary) from emp group by dep;                    orm:                         按哪个字段group by 就 values 哪个字段,用annotate 统计                        1.查询每个部门的名字                        queryset = Emp.objects.values("dep").annotate(c=Count("*"))                        2.查询每个省份的平均薪水                        queryset= Emp.objects.values("province").annotate(avg_salary=Avg("salary"))                2.多表分组:(多张关联表)                    key:多张表join起来,再按单表查                    1.查询每个出版社的名称以及出版过书籍的平均价格                        sql:                            select publish.name,Avg(book.price) from publish left join book on publish.id = book.publish_id                            group by publish.id,publish.name                        orm:                            方式一:                                queryset = Publish.objects.values("name","id").annotate(avg_price =avg("book__price"))                            方式二:                                queryset = Publish.objects.all().annotate(avg_price =avg("book__price"))                    2.查询每一个作者的名字以及出版书籍的个数                        方式一:                            queryset = Author.objects.values("name").annotate(book_num=Count("book"))                        方式二:                            queryset = Author.objects.annotate(book_num=Count("book")).values("book_num","name")                    3.查询每本书籍名称以及作者个数                        queryset = Book.objects.annotate(c=Count("authors")).values("title",c)                    4.查询作者个数大于1的书籍名称和作者个数                        sql:                            select book.tilte,Count(author.id) as c from book left join book2authors on book.id = book2authors.book_id                                                left join Author on book2authors.author_id                                                group by book.id                                               having c>1                        orm:                            queryset = Book.objects.annotate(c=Count("authors")).filter(c__gt=1).values("title","c")                                                                                 (相当于having)                    5.查询书籍名称包含“h"的书籍名称和作者个数                        Book.objects.filter(title__icontains='h').annonate(c=Count('authors')).values("title",c)                                     (相当于where)        ====================================F查询和Q查询===================================================        from django.db.models import F,Q,Avg        1.F查询            1.查询评论数大于100的文章                Article.objects.filter(comment_num__gt=100)            2.查询评论数大于点赞数的文章                Article.objects.filter(comment_num__gt=F(poll_num))            3.查询评论数大于100的所有文章                queryset = Article.objects.filter(comment_num__gt=F("poll_num")*2)            4.将所有书籍的价格提高一百元                Book.objects.update(price=F("price")+100)        2.Q查询 (|或  &且  ~非)            1.查询价格大于200或名称以"p"开头的书籍                queryset = Book.objects.all().filter(Q(price__gt=200)|Q(title__startswith="p")            2.查询价格大于300或出版日期(不是)为2019年一月份的书籍                queryset= Book.objects.filter(Q(price__gt=300)|~Q(Q(pub_date_year=2019)&Q(pub_date_month=1)))
代码

 

 

转载于:https://www.cnblogs.com/knighterrant/p/10386189.html

你可能感兴趣的文章
动态绑定时的显示隐藏控制
查看>>
注意java的对象引用
查看>>
C++ 面向对象 类成员函数this指针
查看>>
inline函数的总结
查看>>
SPSS-生存分析
查看>>
【Jquery】$.Deferred 对象
查看>>
linux IPC
查看>>
HUD-1548
查看>>
app加固
查看>>
Mybatis输入和输出映射(parameterType和resultType的区别)
查看>>
一天一个设计模式:装饰者模式
查看>>
mysql 性能分析及explain用法
查看>>
Oracle 11g R2 listener.ora&tnsnames.ora Sample
查看>>
Android SDK下载和更新慢或失败的解决办法
查看>>
Double保留两位小数
查看>>
UVA1368
查看>>
Peter Norvig:Teach Yourself Programming in Ten Years(自学编程,十年磨一剑)
查看>>
Java 6 JVM参数选项大全(中文版)
查看>>
帝国cms用户密码忘记怎么修改
查看>>
centos7删除PHP怎么操作
查看>>