• ORM 单表操作 & 查询API


    ORM 单表操作 & 查询API

    views.py

    1. 增:book = Book.objects.create(title=title, price=price, pub_date=pub_date, publish=publish)

      from models import Book
      
      # 1 objects 管理器创建 model对象
      book = Book.objects.create(title='python', price=120, pub_date='2020-01-01', publish='上海出版社')
      
      # 2 类实例化创建(不推荐)model对象
      book = Book(title='python', price=120, pub_date='2020-01-01', publish='上海出版社')
      book.save()
      
      # 3 批量创建
      obj_list = []
      for i in range(100):
          obj = Book(title='python%s' % i, price = 120)
          obj_list.append(obj)
      Book.objects.bulk_create(objs)
      
      # 4 有就更新,没有就创建 update_or_create
      Book.objects.update_or_create(title='python', default={price:200})
      # 查找title为‘python'的记录,如果有就把price更新为200
      # 没有就创建这条记录
      
      # 关键字参数可以将字典打散传参
      book = Book.objects.creat(**{title:'python', price:120})
         	
          
      
    2. 删:Book.objects.filter(nid=book_nid).delete()

      QuerySet对象和model对象都可以调用

    3. 改:Book.objects.filter(nid=book_nid).update(title=title,..........)

      QuerySet对象调用

    4. 查: book.objects.all(): select * from book

      ​ book.objects.all().values('title'): select title from book

      ​ 可以简写为: book.objects.values('title')

      models对象: 记录对象, 取值: model对象.属性-- book.title

      QuerySet对象: modes对象的列表, 取值: QuerySet对象[0].属性--[book_obj1, book_obj2,......]--->book_lst[0].title

      • 链式操作: 如果返回的是QuerySet对象,则可以继续调用QuerySet对象的方法

        方法 说明 示例 调用者 返回值
        all() 所有 Book.objects.all() objects管理器 QuerySet对象
        filter(**kwargs) 条件筛选 Book.objects.filter(titile='python') objects管理器 QuerySet对象
        get(**kwargs) 唯一记录,
        0个或超过1个会报错
        Book.objects.get(nid=1) objects管理器 models对象
        first() 查询到的第一条记录 Book.objects.all().first() QuerySet对象 models对象
        last() 查询到的最后条记录 Book.objects.all().last() QuerySet对象 models对象
        exclude(**kwargs) 排除 Book.objects.exclude(titie='python') objects管理器QuerySet对象 QuerySet对象
        order_by(*args) 排序:-降序 Book.objects.all().order_by('-price') QuerySet对象 QuerySet对象
        cout() 统计数量 Book.objces.all().count() QuerySet对象 int
        reverse() 列表反转排序必须在order_by之后 Book.objects.all().order_by('id').reverse() QuerySet对象 QuerySet对象
        exists() 是否存在记录,
        只检查1条记录
        Book.objects.all().exists() QuerySet对象 bool
        values() 针对性的取字段值 Book.objects.all().values('title','price') QuerySet对象 QuerySet键值对字典对象
        values_list() 针对性的取字段的值 Book.objects.all().values_list('title') QuerySet对象 QuerySet 记录元组对象
        distinct() 去重 Book.objects.values('price').distinct() QuerySet对象 QuerySet对象

        模糊查询

        双下划线 条件 示例
        __gt > Book.objects.filter(price__gt=100)
        __lt < Book.objects.filter(price__lt=100)
        __gte >= Book.objects.filter(price__gte=100)
        __lte <= Book.objects.filter(price__lte=100)
        __startswith 以指定字符串开头 Book.objects.filter(title__startswith="py")
        __istartswith 以指定字符串开头,不区分大小写 Book.objects.filter(title__istartswith="py")
        日期字段__year 年份= Book.objects.filter(pub_date__year=2012)
        日期字段__month 月份= Book.objects.filter(pub_date__month=2012)
        日期字段__year__gt 年份> Book.objects.filter(pub_date__year__gt=2012)
        __in=[100,200,300] 3个值任意一个 Book.objects.filter(price__in=[100,200,300])
        __range=[100,200] sql:between and,>=100 <=200 Book.objects.filter(price__range=[100,200])
        __contains 包含 Book.objects.filter(title__contains='py')
        __icontains 包含,不区分大小写
        • mysql日期查询问题:如果明明有结果,却查不出结果,是因为mysql数据库的时区和django的时区不同导致的

          django中的settings配置文件里面的USE_TZ = True改为False

    from django.shortcuts import render, HttpResponse, redirect
    from django.urls import reverse
    from app01.models import Book
    
    
    # Create your views here.
    
    ################## 增加记录 ########################
    def add_book(request):
        """
    
         book = Book.objects.create(title='python', price='80', pub_date='2020-01-01', publish="上海出版社")
        """
        if request.method == 'GET':
            return render(request, 'add_book.html', {'mode': '新增书籍'})
        else:
            # # 常规方法
            # title = request.POST.get('title')
            # price = request.POST.get('price')
            # pub_date = request.POST.get('pub_date')
            # publish = request.POST.get('publish')
            # book = Book.objects.create(title=title, price=price, pub_date=pub_date, publish=publish)
    
            # 添加记录简便方法
            # print(request.POST)
            """
            < QueryDict: {'csrfmiddlewaretoken': ['XI3lD5K8Fu0Z6S4DGLwyTjlX6rNtRgRfrDJBwWiRUprbpnelBmrtDS2PjyT8DDDN'],
                          'title': ['JAVA'], 'price': ['100'], 'pub_date': ['2020-04-13'], 'publish': ['上海出版社']} >
            < QuerySet[ < Book: Book
            object >, < Book: Book
            object >] >
            """
            # 转换POST内容为字典
            data = request.POST.dict()
            print(data)
            del data['csrfmiddlewaretoken']  # 删除csrf_token键值,剩下的就是传入的表单提交的数据
            print(data)
    
            # 将字典打散为关键字参数传入,等价于Book.objects.create(title=title, price=price, pub_date=pub_date, publish=publish)
            Book.objects.create(**data)
    
            url = reverse('new_book')
            return redirect(url)
    
    
    def books(request):
        book_lst = Book.objects.all()  # 查询所有<QuerySet [<Book: Book object>, <Book: Book object>]> QuerySet 类型,所有记录
        # book_lst = Book.objects.filter(title='python')  # 按条件查询
        # print(book_lst)
        # print(book_lst[0].nid)
    
        return render(request, 'books.html', {'book_lst': book_lst})
    
    
    # ################### 删除记录
    def dele_book(request, book_nid):
        Book.objects.filter(nid=book_nid).delete()
    
        url = reverse('new_book')
        return redirect(url)
    
    # ################### 编辑记录
    
    def edit_book(request, book_nid):
        if request.method == 'GET':
            book_lst = Book.objects.filter(nid=book_nid)
            print(book_lst[0].title)
    
            return render(request, 'add_book.html', {'book': book_lst[0], 'mode': '编辑书籍'})
        else:
            title = request.POST.get('title')
            price = request.POST.get('price')
            pub_date = request.POST.get('pub_date')
            publish = request.POST.get('publish')
            Book.objects.filter(nid=book_nid).update(title=title, price=price, pub_date=pub_date, publish=publish)
    
            url = reverse('new_book')
            return redirect(url)
    
    
    #  ################ 查询记录
    def query(request):
        # 1. all() 方法: 由 object管理器调用. 返回QuerySet, models对象的列表, 取值: book_lst[0].title
    
        # <QuerySet [<Book: python从入门到精通>, <Book: linux>, <Book: Go>, <Book: JAVA>, <Book: python从入门到实践>, <Book: python3 面向对象编程>]>
        book_lst = Book.objects.all()  # models.py中,类中添加了__str__属性,显示对象的title : Book: python从入门到精通
        # selece * from  ---> * 效率低
        # django orm 做了优化,select 字段名 可提高效率
        # SELECT `app01_book`.`nid`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`pub_date`, `app01_book`.`publish` FROM `app01_book` LIMIT 21; args=()
        print('all', book_lst)
    
        # 2. filter()方法: objects管理器调用, 返回QuerySet 对象的列表, 取值: book_lst[0].title
        ret = Book.objects.filter(title='JAVA', price=100)  # and
        print('filter', ret)
    
        # 3. get()方法: objects管理器调用, 返回models对象, 可以直接取属性, book.title
        # ### get()方法,获取0个或者超过1个会报错,使用: 按主键查询的可用get,因为主键是唯一的
        book = Book.objects.get(title='Go')
        print('get', book)
        print(book.price)
    
        # 4. first() last()  QuerySet调用, 返回model对象
        first_book = Book.objects.all()[0]
        first_book = Book.objects.all().first()  # 第一个model对象, 可以直接 .属性 取值
    
        last_book = Book.objects.all().last()  # 最后一个model对象
        print('first', first_book, 'last', last_book)
    
        # 5. exclude(**kwargs): 排除  objects管理器调用 对象调用,返回QuerySet对象
        exclude_book = Book.objects.exclude(price=100)  # price不等于100的记录, 返回QuerySet对象
        print('exclude', exclude_book)
    
        # 6. order_by: 排序  由QuerySet调用, 返回QUerySet
        order_book = Book.objects.all()  # 默认按主键排序, 升序
        print('order_by all', order_book)
        order_book = Book.objects.order_by('price')  # 默认升序
        print('order_by 按price升序', order_book)
        order_book = Book.objects.order_by('-price')  # - 降序
        print('order_by 按price降序 -price', order_book)
        order_book = Book.objects.order_by('price', 'nid')  # 先按price排序,price一样再按nid排序
        print('order_by price, nid', order_book)
        # ## 链式操作, 如果返回的是QuerySet对象,则继续可以调用QuerySet对象的方法继续调用
        # #### 获取price最大的记录
        max_price_book = Book.objects.all().order_by('-price').first()
        print('price最大的记录:', max_price_book)
    
        # 7. count(): 统计数量 由QuerySet对象调用,返回值: int
        book_count = Book.objects.count()
        print('count', book_count)
        book_count = Book.objects.all().count()
        print('count', book_count)
        book_count = Book.objects.all().filter(price=100).count()
        print('count price=100', book_count)
    
        # 8. reverse(): 反转: 由QuerySet对象调用, 返回值:QuerySet
        # 必须在order_by之后
        order_by_normal = Book.objects.order_by('price')
        print('order_by 正序', order_by_normal)
        order_by_reverse = Book.objects.order_by('price').reverse()
        print('order_by 反转', order_by_reverse)
    
        # 9. exists(): 是否存在记录 由QuerySet对象调用,返回值:bool
        is_exists = Book.objects.exists()  # Book.objects.all().exists()
        # SELECT (1) AS `a` FROM `app01_book` LIMIT 1; args=()
        # SQL语句的LIMIT, 限制返回查询的结果数量, exists() 就是只取1条记录,如果没有则不存在记录
        if is_exists:
            print('ok')
    
        # **************************************************************************************** #
        # 10. values(): 针对性的取字段的值, 由QuerySet对象调用,返回QuerySet对象,形式不是保存记录对象的QuerySet,而是保存的记录键值对{字段: 值}的字典,每一个字典代表一条记录
        # <QuerySet [{'title': 'python从入门到精通', 'price': Decimal('100.00')}, {'title': 'linux', 'price': Decimal('80.00')}>
        ret = Book.objects.all()
        print('all', ret)
        ret = Book.objects.all().values('title', 'price')
        print('values', ret)
        """
        内部源码剖析
        
        def values():
            ret = []
            for obj in Book.objects.all():
                tmp = {
                    'title': obj.title,
                    'price': obj.price
                }
                ret.append(tmp)
            return ret
        
        """
    
        # 11. values_list():针对性的取字段的值, 由QuerySet对象调用,返回QuerySet对象,是保存的记录的元组,每一个元组代表一条记录	
        # <QuerySet [('python从入门到精通', Decimal('100.00')), ('linux', Decimal('80.00'))
        ret = Book.objects.filter(price=100).values_list()
        ret = Book.objects.all().values_list('title', 'price')
        print(ret)
    
        # 12. distinct(): 去重   由QuerySet调用, 返回值QuerySet
        ret = Book.objects.all().distinct()  # 没有重复的值,因为有主键是唯一的
        print('all 去重无效,主键唯一', ret.count())
        ret = Book.objects.all().values('title').distinct()
        print('values 去重', ret.count())
    
        # ************************************模糊查询********************************************** #
        # 双下划线__
        ret = Book.objects.filter(price__gt=100)  # gt:  >
        print('>', ret)
    
        ret = Book.objects.filter(price__lt=100)  # lt:  <
        print('<', ret)
    
        ret = Book.objects.filter(price__gte=100)  # gte: >=
        print('>=', ret)
    
        ret = Book.objects.filter(title__startswith="py").values("title")  # 以指定字符串开头
        print('startswith 以py开头', ret)
    
        ret = Book.objects.filter(title__istartswith="py").values("title")  # 以指定字符串开头,不区分大小写
        print('istartswith 以py开头 不区分大小写', ret)
    
        return HttpResponse('查询成功')
    
    
  • 相关阅读:
    zabbix 主被动模式
    MySQL角色(role)功能介绍
    MySQL权限管理实战
    创建索引,这些知识应该了解
    MySQL锁等待与死锁问题分析
    Navicat操作MySQL简易教程
    职场里,对数据库要有敬畏之心!
    MySQL字段默认值设置详解
    MySQL查看及杀掉链接方法大全
    MySQL字段类型最全解析
  • 原文地址:https://www.cnblogs.com/relaxlee/p/12843067.html
Copyright © 2020-2023  润新知