ORM 单表操作 & 查询API

Posted relaxlee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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(‘查询成功‘)

以上是关于ORM 单表操作 & 查询API的主要内容,如果未能解决你的问题,请参考以下文章

Django框架05 /orm单表操作

Django之模型层&ORM操作

Django基础五之django模型层单表操作

Django ORM 操作 必知必会13条 单表查询

ORM 单表操作查询 多表操作查询及增删改查

17-2 orm单表操作和多表操作