zoukankan      html  css  js  c++  java
  • day55

    模板层

    配置测试文件

    1. 第一种

    当你想单独测试django中的某一个py文件的时候,你需要手动配置测试脚本文件直接在某一个应用下的tests文件中书写下面的内容(去manage.py文件中拷贝前4行代码),然后自己写两行代码即可,去掉import sys,然后加上两句代码即可

    import os
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
        然后在下面添加两条语句
        import django
        django.setup()
        
        
    一定要等到测试脚本搭建完成后  才能导入django文件进行测试
    from app01 import models
    
    1. 第二种

      直接新建一个任意名称的py文件 在里面也写上面的配置 也可以配置

    import os
    if __name__ == "__main__":
    							os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day53.settings")
    
    							import django
    							django.setup()
    							
    							# 一定要等待测试脚本搭建完毕之后 才能导入django文件进行测试
    							from app01 import models
    							
    

    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即可查看查询语句:
    from app01 import models
    user_obj = models.User.objects.all}()
    即可打印出获取user_obj锁所进行的sql语句
    
    

    创建数据表

    1. create方法

      # book_obj = models.Books.objects.create(title='三国演义',price=123.23,publish_date='2019-11-11')
      # print(book_obj)
      # from datetime import date
      # ctime = date.today()
      # book_obj = models.Books.objects.create(title='红楼梦', price=888.99, publish_date=ctime)
      # print(book_obj)
      
    2. 利用对象的绑定方法

      # book_obj = models.Books(title='西游记',price=666.66,publish_date='2000-1-21')
      # book_obj.save()
      

      修改数据

       # res = models.Books.objects.filter(pk=1)
       pk(就是主键)会自动帮你查找当前表的主键字段   所以后期我们都是用pk来代替主键字段
       filter查询出来的结果是一个Queryset对象
       
       1.只要是Queryset对象就可以无限制的调用Queryset的方法
       res= models.Books.objects.filter(pk=1).filter().filter().filter()
       
       2.只要是Queryset对象就可以点query查看当前结果内部对应的sql语句
       res.query
       SELECT `app01_books`.`id`, `app01_books`.`title`, `app01_books`.`price`, `app01_books`.`publish_date` FROM `app01_books` WHERE `app01_books`.`id` = 1 
      
      方式一  利用queryset方法
      models.Books.objects.filter(pk=1).update(price=444.66)
      
      方式二  利用对象
      book_obj = models.Books.objects.get(pk=1)
      book_obj.price = 222.66
      book_obj.save()   该方法不推荐使用   推荐使用Queryset方法
      利用对象的修改  内部其实是从头到尾的将数据的所有的字段重新写一遍
      
      get和filter的区别
      1.filter获取到的是一个Queryset对象  类似于一个列表
      
      2.get获取到的直接就是数据对象本身
      
      当条件不存在的情况下  
      filter不会报错直接返回一个空   推荐使用filter方法
      get直接报错  所以不推荐使用get方法
      
      

      删除数据

      1.利用Queryset方法  delete()
      models.Books.objects.filter(pk=1).delete()
      2.对象方法
      book_obj = models.Books.object.get(pk=2)
      book_obj.delete()
      
      

    13种查询数据

    如果你想查看所有的orm语句 内部对应的sql语句
    
    你可以直接在配置文件中配置相应的代码即可
    
    ```
    1.all()查询所有   返回的结果Queryset对象
    res=models.Books.objects.all()
    print(res)
    
    orm语句的查询默认的都是惰性的查询
    只有当你真正的使用数据的时候才会执行orm语句
    
    2.filter()  筛选  相当于你原生的sql语句里面的where关键字   返回的结果Queryset对象
    res = models.Books.objects.filter(pk=1,title='三')   支持多个参数  并且是and的关系
    print(res)
    
    3.get()   筛选  获取的是数据本身   条件不存在直接报错  并且查询条件 必须是唯一的  数据对象
    res = models.Books.objects.get(title='西游记')
    res1 = models.Books.objects.filter(title='西游记')
    print(res,res1)
    print(res1)
    
    4.first()   获取Queryset中的第一个对象  数据对象
    res=models.Books.objects.filter(title='西游记').first()
    print(res.price)
    
    5.last()  取Queryset中的最后一个对象  数据对象
    res=models.Books.objects.filter(title='西游记').last()
    print(res.price)
    
    6.count()  统计数据的个数   数字
    num =models.Books.objects.count()
    print(type(num))
    
    7.values()   获取数据对象中指定的字段的值  可以有多个  queryset   列表套字典
    res = models.Books.objects.('title','price')
    print(res)
        # <QuerySet [{'title': '三国演义', 'price': Decimal('222.66')}, {'title': '红楼梦', 'price': Decimal('888.99')}, {'title': '西游记', 'price': Decimal('444.66')}, {'title': '西游记', 'price': Decimal('666.22')}]>
    
    8.values_list()   获取数据对象中指定的字段的值  可以有多个 queryset   列表套元组
    res = models.Books.objects.values_list('title','price')
    print(res)
        # <QuerySet [('三国演义', Decimal('222.66')), ('红楼梦', Decimal('888.99')), ('西游记', Decimal('444.66')), ('西游记', Decimal('666.22'))]>
    
    9.order_by()   按照指定的字符串排序
    res = models.Books.objects.order_by('price')  # 默认是升序
    res1 = models.Books.objects.all().order_by('price')  # 默认是升序   两者等价 下面的方式 语义更明确
    降序  字段前面加负号
    res1 = models.Books.objects.all().order_by('-price')
    print(res1)
    
    10.reverse()      颠倒顺序   前提是跌倒的对象必须有顺序(提前排序之后才能跌倒)
    res = models.Books.objects.all()
    res1 = models.Books.objects.all().reverse()
    res2 = models.Books.objects.all().order_by('price')
    res3 = models.Books.objects.all().order_by('price').reverse()
    print(res2,res3)
    


    ​ 11.exclude() 排除什么什么之外 queryset对象
    ​ res = models.Books.objects.all().exclude(title='三国演义')
    ​ print(res)
    ​ <QuerySet [<Books: 红楼梦>, <Books: 西游记1>, <Books: 西游记2>]>

    12.exists() 判断查询结果是否有值 返回结果是一个布尔值
    res = models.Books.objects.filter(pk=1).exists()
    print(res)
    该方法其实不需要使用 因为数据本身自带布尔值

    13.distinct()    对查询结果进行去重操作     去重的前提:数据必须是完全想要的情况下 才能够去重(你容易忽略主键)
    res = models.Books.objects.values('title','price')
    res = models.Books.objects.values('title','price').distinct()
    print(res)
    

    双下划线查询

    查询价格大于500的书籍
    res=models.Books.objects.filter(price_gt=500)     gt大于500
    print(res)
    
    查询价格小于500的书籍
    res=models.Books.objects.filter(price_lt=500)     lt小于500
    print(res)
    
    查询价格大于等于500的书籍
    res=models.Books.objects.filter(price_gte=444.15)   gte大于等于500
    res=models.Books.objects.filter(price_gte=500)
    print(res)      对数字精度不敏感
    
    查询价格小于等于500的书籍
    res=models.Books.objects.filter(price_lte=500)
    print(res)  
    
    查询价格在200或者444之或者500的书籍
    res=models.Books.objects.filter(price_in=[222,444,500])
    print(res) 
    
    查询价格在222到800之间的书籍
    res=models.Books.objects.filter(price_range=(222,800))
    print(res) 
    
    查询出版日期是2019年的书籍
    res=models.Books.objects.filter(publish_date__year='2019')
    print(res) 
    
    查询出版日期是1月份的书籍
    res=models.Books.objects.filter(publish_date__month='1')
    print(res) 
    

    模糊查询

        """
        MySQL中的模糊查询
            关键字 like
                模糊匹配的符号
                    %:匹配任何个数的任意字符
                    _:匹配一位任意的字符
        """
        
        查询书籍是以三开头的书
        res = models.Books.objects.filter(title__startswith='三')
        print(res)
        
        查询书籍是以义结尾的书
        res = models.Books.objects.filter(title__endswith='义')
        print(res)
        
        查询书籍名称中包含游字的书籍
        res = models.Books.objects.filter(title__contains='游')
        print(res)
        
        查询书籍名称中包含字母p的书籍
        res = models.Books.objects.filter(title__contains='p')  # 默认区分大小写
        
        res = models.Books.objects.filter(title__icontains='p')  # 忽略大小写 加i
        print(res)   
    

    一对多字段的增删改查

        增
        第一种
        models.Book.objects.create(title='三国演义',price=222.33,publish_id=1)  # 直接传表里面的实际字段 跟数据主键值  publish_id
        第二种
         publish_obj = models.Publish.objects.filter(pk=2).first()
         models.Book.objects.create(title='红楼梦',price=444.33,publish=publish_obj)      # 传虚拟字段  跟数据对象即可
         
         改
         第一种
         models.Book.object.filter(pk=1).update(publish_id=2)
         
         第二种
         publish_obj = models.Publish.object.filter(pk=1).first()
         models.Book.object.filter(pk=1).update(publish=publish_obj)
         
         删
         models.Publish.objects.filter(pk=1).delete() 默认就是级联删除  级联更新
    

    多对多字段的增删改查

    增
    book_obj = models.Book.objects.filter(pk=1).first()
    print(book_obj.publish)   点外键字段  可能会直接获取到外键关联的数据对象
    给当前这一本书绑定作者
    麻瓜式的操作   自己直接去操作第三张表
    print(book_obj.authors)   已经跨到第三张表了
    book_obj.authors.add(1)   第三张表里给书籍绑定一个主键为1的作者
    book_obj.authors.add(1,2)   第三张表里给书籍绑定一个主键为1和2的作者
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    book_obj.authors.add(author_obj)
    book_obj.authors.add(author_obj,author_obj1)
    add方法  能够朝第三张表添加数据
    即支持传数字add(1,2) 
    也支持传对象add(author_obj,author_obj1)
    并且两者都可以是多个
    
    改
    book_obj = models.Book.object.filter(pk=2).first()
    book_obj.authors.set((1,3))
    book_obj.authors.set([1,])
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    book_obj.authors.set((author_obj,author_obj1))
    set修改多对多关系表中的数据  
    既可以传数字   也可以传对象
    但是需要注意的是括号内必须是可迭代的对象
    都支持多个
    set((1,3))
    set((author_obj,author_obj1))
    
    删
    book_obj = models.Book.object.filter(pk=2).first()
    book_obj.authors.remove(100)
    book_obj.authors.remove(1,2)
    author_obj = models.Author.objects.filter(pk=1).first()
    author_obj1 = models.Author.objects.filter(pk=2).first()
    book_obj.authors.remove(author_obj)
    book_obj.authors.remove(author_obj,author_obj1)
    remove既可以传数字  也可以传对象
    并且都支持传多个   不需要迭代
    remove(1,2)
    remove(author_obj,author_obj1)
    
    清空  删除某个数据在第三张表中的所有的记录
    book_obj = models.Book.object.filter(pk=2).first()
    book_obj.author.clear()
    clear清空书籍相关的所有记录  括号内不需要传递参数
    注意:对于foreignkey对象,clear()和remove()方法仅在null=True时存在
    注意:对于所有类型的关联字段,add()、create()、remove()和clear(),set()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法
    

    跨表查询

    跨表查询
    
    正反向查询
    
    关系字段在哪张表  由谁查谁就是正向
    
    如果关系字段   就是反向
    
    反向查询按表名小写+_set 
    
    
    基于对象的跨表查询   子查询  分步操作
    1.查询书籍主键为2的出版社名称
    book_obj = models.Book.object.filter(pk=2).first()
    print(book_obj.publish)    出版社对象
    print(book_obj.publish.name)
    
    2.查询书籍主键为4的作者姓名
    book_obj = models.Book.object.filter(pk=2).first()
    print(book_obj.authors)   # app01.Author.None
    print(book_obj.authors.all())
    
    3.查询作者是jason的手机号
    author_obj = models.Author.objects.filter(name='jason').first()
    print(author_obj.author_detail)
    print(author_obj.author_detail.phone)
    什么时候需要加all
    当正向查询点击外键字段数据有多少个的情况下  需要.all()
    app01.Author.None   一旦看到该结果  只需要加.all()即可
    在写orm语句的时候跟你写sql语句一样  不要想着一次性写完
    写一点查一点再写一点
    
    4.查询出版社是东方出版社出版过的书籍
    publish_obj = models.Publish.objects.filter(name='东方出版社').first()
    print(publish_obj.book_set)   #app01.Author.None 
    print(publish_obj.book_set.all()) 
    
    5.查询作者是jason写过的书籍
    author_obj = models.Author.objects.filter(name='jason').first()
    print(author_obj.book_set)    #app01.Author.None 
    print(author_obj.book_set.all())
    
    6.查询手机号是120的作者姓名
    author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()
    print(author_detail_obj.author)
    print(author_detail_obj.author.email)
    
    什么时候反向查询的时候表名小写需要加_set
    一对多
    多对多
    的情况下
    
    一对一的情况下不要加_set
    

    基于双下划线的跨表联表查询

    基于双下划线的跨表查询    联表操作
    
    inner join
    left  join
    right join
    union
    
    1.查询书籍pk为2的出版社名称
    正向
    res=models.Book.objects.filter(pk=2).values('publish__name')
    写外键字段就相当于已经跨到外键字段所在的关联的表中
    你想要改表的哪些字段的信息   你只需要加__获取即可
    print(res)
    反向
    res=models.Publish.objects.filter(book__pk=2).values('name')
    print(res)
    
    2.查询书籍pk为2的作者姓名和邮箱
    res=models.Book.objects.filter(pk=2).values('author__name','author__email')
    print(res)
    反向
    res=models.Author.objects.filter(book__pk=2).values('name','email')
    print(res)
    
    models后面点的谁   就以谁为基表
    
    3.查询作者为egon的家庭住址
    res=models.Author.objects.filter(name='egon').values('author_detail__addr')
    print(res)
    反向
    res=models.AuthorDetail.objects.filter(author__name='egon').values('addr')
    print(res)
    
    4.查询出版社是东方出版社出版过的书名的名字
    res=models.Publish.objects.filter(name='东方出版社').values('book_title')
    print(res)
    res=models.Book.objects.fliter(publish__name='东方出版社').values('title')
    print(res)
    
    查询书籍pk是2的作者的手机号
    res=models.Book.object.filter(pk=2).values('author__author_detail__phone')
    print(res)
    res=models.Author.objects.filter(book__pk=2).values('author_detail__phone')
    

    数据库迁移提示错误的问题解决

    数据库迁移的时候报错提示没有安装mysqldb模块,去安装MySQLclient然后去models,再次执行迁移命名,可以把数据迁移到数据库中,但是会提示:系统检查发现一些问题:提示一个WARNINGS警告提示: ?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
    HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it. See: https://docs.djangoproject.com/en/2.1/ref/databases/#mysql-sql-mode 但是不影响迁移,再配置下面的参数就行了

    然后去settings中配置:

    增加黄色配件的配置:
    
    DATABASES = {
        'default': {
            # 'ENGINE': 'django.db.backends.sqlite3',
            # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'erebus',
            'USER': 'root',
            'PASSWORD': 'root',
            'HOST': '127.0.0.1',
            'PORT': '3306',
            'OPTIONS': {
                "init_command": "SET sql_mode='STRICT_TRANS_TABLES'",
            }
        }
    }
    

    必须加上'OPTIONS': { "init_command": "SET sql_mode='STRICT_TRANS_TABLES'", }

    这样就解决问题了。

  • 相关阅读:
    jQuery 简单滑动轮播图效果
    西工大:同学你好,回来挂科!
    【入门】产品经理零基础怎么入门?
    【考点】 HashMap,HashTable,CurrentHashMap,LinkedHashMap,TreeMap简述
    P图鬼才们集体上线!高校毕业照P图哪家强?
    【实战】怎样实现前端裁剪上传图片功能
    校招选产品经理岗?给你浇盆水
    战胜70%对手的校招开发岗简历是这个样子的
    两个人遇到熊,装死的和转身跑的,哪个能活下来
    第一份实习工作,我应该学到什么?
  • 原文地址:https://www.cnblogs.com/gfhh/p/11946000.html
Copyright © 2011-2022 走看看