• Django基础(三)


    #models.py
    from django.db import models
    
    class Book(models.Model):
        nid=models.AutoField(primary_key=True)
        title=models.CharField(max_length=32)
        pubDate=models.DateField()
        price=models.DecimalField(max_digits=6,decimal_places=2)
        read_num=models.IntegerField(default=0)
        comment_num=models.IntegerField(default=0)
        
        #书籍与出版社:一对多
        publisher=models.ForeignKey('Publish', related_name='bookList')
    
        #书籍与作者:多对多
        authors=models.ManyToManyField('Author')
    
        def __str__(self):
            return self.title
    
    class Publish(models.Model):
        name=models.CharField(max_length=32)
        addr=models.CharField(max_length=32)
        tel=models.BigIntegerField()
    
        def __str__(self):
            return self.name
    
    class Author(models.Model):
        name=models.CharField(max_length=32)
        age=models.IntegerField()
        tel=models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    class AuthorDetail(models.Model):
        addr=models.CharField(max_length=32)
        author=models.OneToOneField('Author')
    
    #生成的第三张表的表名是 app01_book_authors,但是我们不能直接操作这张表

    ORM跨表添加

    1.一对多添加

    1.publish_obj=Publish.objects.get(id=2)
    表.objects.create(title='python',publisher=publish_obj)
    2.表.objects.create(title='python',publisher_id=2)

    2.多对多添加

    authors=models.ManyToManyField('Author')  #与这本书关联的作者对象集合
    
    book_obj=models.Book.objects.create(title=title,pubDate=pubdate,price=price,publisher_id=publish_id)
    
    #方式1
    print(book_obj.authors.all())  #QuerySet  []
    alex=models.Author.objects.get(name='alex')
    egon=models.Author.objects.get(name='egon')
    #绑定关系
    book_obj.authors.add(alex,egon)   
    print(book_obj.authors.all())  #QuerySet  [author_alex,author_egon]
    #方式2
    author_list=models.Author.objects.all()
    book_obj.authors.add(*author_list)
    
    #解除关系
    book_obj=models.Book.objects.get(nid=14)
    print(book_obj.authors.all())
    alex=models.Author.objects.get(name='alex')
    book_obj.authors.remove(alex)
    
    author_list=models.Author.objects.filter(id__gt=1)
    book_obj.authors.remove(*author_list)
    
    #清空
    book_obj.authors.clear()

    ORM跨表查询

    1.基于对象的跨表查询

    正向查询按字段,反向查询按表名(小写)_set

    一对多跨表查询
    
    1.查询python这本书出版社的地址
    book_obj=Book.objects.get(title=python)
    book_obj.publisher.addr
    多对多跨表查询
    
    1.查询python这本书的所有作者的姓名和年龄
    
    book_python=models.Book.objects.get(title='python')
    author_list=book_python.authors.all()
    for author in author_list:
        print(author.name,author.age)
    
    
    book_python=models.Book.objects.filter(title='python')
    for book_python in book_pythons:
        author_list=book_python.authors.all()
        for author in author_list:
            print(author.name,author.age)
    1.查询人民出版社出版过的书籍名称及价格
    
    pub_obj=models.Publish.objects.get(name='renmin')
    book_list=pub_obj.book_set.all() 或 book_list=pub_obj.bookList.all() #Query  与这个出版社关联的所有书籍对象
    
    for obj in book_list:
        print(obj.title,obj.price)
    
    
    2.alex出版过的所有书籍的名称
    
    alex=models.Author.objects.get(name='alex')
    book_list=alex.book_set.all()
    for book in book_list:
        print(book.title,book.price)
    一对一正向查询
    
    查询addr在沙河的作者
    authorDetail=models.AuthorDetail.objects.get(addr='shahe')
    print(authorDetail.author.name)
    
    
    一对一反向查询:按表名(小写),不需要加_set
    
    查询alex在哪里
    alex=models.Author.objects.get(name='alex')
    alex.authordetail.addr

    2.基于双下划线的跨表查询

    正向查询按字段,反向查询按关联的表名

    #查询python这本书的价格
    ret=models.Book.objects.filter(title='python').values('price','title')
    print(ret)
    #查询python这本书出版社的地址和名称
    
    正向查询:按字段
    ret2=models.Book.objects.filter(title='python').values_list('publisher__name','publisher__addr')
    print(ret2)
    反向查询:按表名
    ret3=models.Publish.objects.filter(bookList__title='python').values_list('name','addr')
    print(ret3)
    #查询人民出版社出版过的所有书籍名称和价格
    models.Book.objects.filter(publisher__name='renmin').values('title','price')
    
    models.Publish.objects.filter(name='renmin').values('bookList__name','bookList_price')
    #查询egon出版过的所有书籍的名字(多对多)
    models.Author.objects.filter(name='egon').values('book__title')
    
    models.Book.objects.filter(authors__name='egon').values('title')
    #地址以沙河开头的作者出版过的所有书籍名称以及出版社名称
    ret=models.Book.objects.filter(authors__authordetail__addr__startswith='sha').values('title','publisher__name')
    print(ret.count())

    聚合与分组

    1.聚合函数 SUM AVG MIN MAX COUNT
    2.聚合函数可以单独使用,不一定要和分组配合使用;只不过聚合函数与group by搭配

    aggregate()

    #单纯聚合函数
    #计算所有图书的平均价格
    from django.db.models import Avg,Count,Sum,Min,Max
    
    models.Book.objects.all().aggregate(Avg('price')) 

    annotate()  返回queryset

    为QuerySet重的每一个对象都生成一个独立的汇总值
    #统计每一本书的作者个数
    ret=models.Book.objects.all().annotate(auathors_num=Count('authors'))
    for obj in ret:
        print(obj.nid,obj.title,obj.author_num)
    
    
    #查询每一个出版社出版过的所有书籍的总价格
    ret=models.Publish.objects.all().annotate(priceSum=Sum('bookList__price'))
    for obj in ret:
        print(obj.id,obj.name,obj.priceSum)
    或
    ret=models.Book.objects.all().values('publisher__name').annotate(priceSum=Sum('price')).values('publisher__name','priceSum')

    F查询与Q查询

    from django.db.models import F,Q
    
    ret1=models.Book.objects.filter(comment_num__gt=50)
    ret2=models.Book.objects.filter(comment_num__gt=F('read_num'))
    #评论数大于2倍阅读数的文章
    ret3=models.Book.objects.filter(comment_num__gt=F('read_num')*2)
    #给每本书涨价10元
    models.Book.objects.all().update(F('price')+10)
    #查询评论数大于500或阅读数也大于50并且价格低于100
    models.Book.objects.filter((Q(comment_num__gt=50)|Q(read_num__gt=50))&Q(price__lt=100))
  • 相关阅读:
    SQL一条语句统计记录总数及各状态数
    火狐登录国际账户
    HTML基础笔记
    增强for、lambda for、stream 遍历List 结束方法 or 跳过循环本次循环
    nginx
    前端问题总结
    Node.js
    Actuator
    ssh免密登录实现及Python实现
    【Mac渗透测试】之SQL注入Demo
  • 原文地址:https://www.cnblogs.com/Ryans-World/p/7883098.html
Copyright © 2020-2023  润新知