zoukankan      html  css  js  c++  java
  • Python Day 72 Django框架 图书管理系统回顾ORM 正向查询、反向查询、跨表查询、Django终端打印SQL语句、ORM十三个必会操作总结

      ##基础数据准备

    #数据模板准备
      图书表、出版社、作者表、作者详情表、
    #表之间的关系
      图书表 和 出版社 一对多
      图书表 和 作者表 多对多
      作者表 和 作者详情表 一对一 (这里专门把作者表拆成两张表来练习orm操作)
    #细节
      1、
    多对多字段建在查询频率比较高的那张表中
      2、多对多的字段只是一个虚拟字段、在数据库中不显示
        # 告诉django orm自动帮你创建第三张表
        # 查询的时候 可以借助该字段跨表
    #要执行两条数据迁移命令:
    
    python3 manage.py makemigrations
    python3 manage.py migrate
    fromdjango.dbimportmodels#Createyourmodelshere.fromdjango.confimportsettingsfromdjango.dbimportmodels#Createyourmodelshere.#图书表classBook(models.Model):title=models.CharField(max_length=32)price=models.CharField(max_length=32)publish_date=models.DateField(auto_now_add=True)#外键字段publish=models.ForeignKey(to='Publish')#多对多字段建在查询频率比较高的那张表中authors=models.ManyToManyField(to='Author')#authors只是一个虚拟字段#告诉djangoorm自动帮你创建第三张表#查询的时候可以借助该字段跨表def__str__(self):returnself.title#必须返回一个字符串类型否则直接报错#出版社classPublish(models.Model):name=models.CharField(max_length=32)addr=models.CharField(max_length=32)email=models.EmailField()def__str__(self):returnself.name#作者classAuthor(models.Model):name=models.CharField(max_length=32)age=models.CharField(max_length=32)#一对一字段也应该建在查询频率较高的表中author_detail=models.OneToOneField(to='AuthorDetail')def__str__(self):returnself.name#作者详情表classAuthorDetail(models.Model):phone=models.CharField(max_length=32)addr=models.CharField(max_length=32)def__str__(self):returnself.phone
    models.py

      ##Django终端打印SQL语句

    如果你想知道你对数据库进行操作时,Django内部到底是怎么执行它的sql语句时可以加下面的配置来查看
    在Django项目的settings.py文件中,在最后复制粘贴如下代码:
    
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console':{
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }
    
    配置好之后,再执行任何对数据库进行操作的语句时,会自动将Django执行的sql语句打印到pycharm终端上
    
    补充:
    除了配置外,还可以通过一点.query即可查看查询语句,注意只能是queryset对象

      ##怎样在Django项目中直接测试orm语句

    #在app01目录下test.py文件
    import os
    import sys
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day72.settings")#该句在manage.py文件中可以直接拷贝过来
        import django
        django.setup()  #手动配置完毕 便可以在下面进行测试

      ##ORM操作

    from django.test import TestCase
    
    # Create your tests here.
    import os
    import sys
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day72.settings")
        import django
        django.setup()
        from app01 import models
        # 只有quertset对象才可以查看sql语句
        # print(models.Publish.objects.all().query)
    
        # (一对多表)外键字段的增删改查
        #
        # 传数字
        # models.Book.objects.create(title='红楼梦',price='199',publish_id=1)
        # 传对象
        # publish_obj = models.Publish.objects.filter(pk=2).first()
        # models.Book.objects.create(title='红楼梦',price='199',publish=publish_obj)
    
        # 修改
        # models.Book.objects.filter(pk=1).update(publish_id=3)
        # 传数字
        # publish_obj = models.Publish.objects.filter(pk=1).first()
        # # 传对象
        # models.Book.objects.filter(pk=2).update(publish=publish_obj)
        
        (多对多 第三张表) 外键字段的增删改查
        # add即可以传数字 也可以传对象  还支持传多个  单个单个的参数 不要传容器类型
        # book_obj = models.Book.objects.filter(pk=1).first()
        # # book_obj.authors.add(1) #跨到第三张表
        # author_obj = models.Author.objects.all()
        # book_obj.authors.add(*author_obj)
        #
        # author_list = models.Author.objects.all()
        # print(author_list)
        # book_obj.authors.add(*author_list)
    
    
        # remove
        # book_obj = models.Book.objects.filter(pk=1).first()
        # book_obj.authors.remove(1)
        # book_obj.authors.remove(2,3)
        # 放对象也可以
    
        # set
        # book_obj = models.Book.objects.filter(pk=1).first()
        # # book_obj.authors.set([1,])
        # author_list = models.Author.objects.all()
        # book_obj.authors.set(author_list)
    
        # clear
        # book_obj = models.Book.objects.filter(pk=1).first()
        # book_obj.authors.clear()  # 清空当前对象所对应的多对多关系
    
        """
        add
        remove
        set
        上面三个可以传一个或多个参数  并且即可以是数字也可以是对象
        clear
        不传参数 直接清空    
        """
        """
        正向
        
        反向
        
        # 正向与方向的概念解释
    
        # 一对一
        # 正向:author---关联字段在author表里--->authordetail        按字段
        # 反向:authordetail---关联字段在author表里--->author        按表名小写
            # 查询jason作者的手机号   正向查询
            # 查询地址是 :山东 的作者名字   反向查询
          
        # 一对多
        # 正向:book---关联字段在book表里--->publish        按字段
        # 反向:publish---关联字段在book表里--->book        按表名小写_set.all() 因为一个出版社对应着多个图书
        
        # 多对多
        # 正向:book---关联字段在book表里--->author        按字段
        # 反向:author---关联字段在book表里--->book        按表名小写_set.all() 因为一个作者对应着多个图书
        """
        # 基于对象的跨表查询  (都是子查询)
        # 1.查询书籍是红楼梦的出版社的名称
        # book_obj = models.Book.objects.filter(title='红楼梦').first()
        # print(book_obj.publish.name)
        # 2.查询东方出版社出版的所有的书
        # publish_obj = models.Publish.objects.filter(name='东方出版社').first()
        # print(publish_obj.book_set)  # app01.Book.None
        # print(publish_obj.book_set.all())
        # 3.查询作者是jason的写过的所有的书
        # author_obj = models.Author.objects.filter(name='jason').first()
        # print(author_obj.book_set)  # app01.Book.None
        # print(author_obj.book_set.all())
        # 4.查询作者jason的住址
        # author_obj = models.Author.objects.filter(name='jason').first()
        # print(author_obj.author_detail.addr)
        # 5.查询手机号是110的作者姓名
        # author_detail = models.AuthorDetail.objects.filter(phone='110').first()
        # print(author_detail.author.age)
    
        """
        基于对象的反向查询 除了一对一直接点表名小写就可以拿到关联对象
        一对多个多对多反向都必须 表名小写_set
        """
        # 基于双下划线的跨表查询 (都是联表查询)
        # 1.查询书籍是红楼梦的出版社名称
        # res = models.Book.objects.filter(title='红楼梦').values('publish__name')
        # print(res)
        # 2.查询书籍是红楼梦的作者姓名
        # res = models.Book.objects.filter(title='红楼梦').values('authors__name','title')
        # print(res)
        # 3.查询作者jason的手机号
        # res = models.Author.objects.filter(name='jason').values('author_detail__phone')
        # print(res)
        # 4.查询书籍是红楼梦的作者的手机号
        # res = models.Book.objects.filter(title='红楼梦').values('authors__author_detail__phone')
        # print(res)
    
        # 反向查询
        # 1.查询出版社为东方出版社的所有图书的名字和价格
        # res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price','name')
        # print(res)(正查)
        # res1 = models.Book.objects.filter(publish__name='东方出版社').values('title','price')
        # print(res1)(反查)
    
        # 2.查询作者姓名是jason的手机号
        # res = models.Author.objects.filter(name='jason').values('author_detail__phone')
        # print(res)(正查)
        # res1 = models.AuthorDetail.objects.filter(author__name='jason').values('phone')
        # print(res1)(反查)
    
    
        # def func():
        #     pass
        # func.name = 'hahaha'
        # print(func.name)
    test.py

      ##ORM十三个必会操作总结

    #1、返回QuerySet对象的方法有
    all()
    filter()
    exclude()
    order_by()
    reverse()
    distinct()
    #2、特殊的QuerySet
    values()       返回一个可迭代的字典序列
    values_list() 返回一个可迭代的元祖序列
    #3、返回具体对象的
    get()
    first()
    last()
    #4、返回布尔值的方法有:
    exists()
    #5、返回数字的方法有
    count()
  • 相关阅读:
    Ubuntu 18.04 上使用xrdp远程桌面登录蓝屏解决
    给定几个字母,输出所有可能的组合(使用递归解决)
    docker容器启动参数
    群辉6.1.7安装scrapy框架执行爬虫
    python爬虫在解析不带引号的json报错的问题解决方案
    python的datetime常用方法
    Ubutntu安装docker启动报Removed /etc/systemd/system/docker.service.
    Django admin argument to reversed() must be a sequence
    linux(乌班图)下执行pip没有问题,执行sudo pip报错的问题
    Robot Framework 关键字操作实例
  • 原文地址:https://www.cnblogs.com/liangzhenghong/p/11278774.html
Copyright © 2011-2022 走看看