• Django ORM 单表操作


    Django ORM单表操作

    img

    Django 测试环境搭建

    注意pycharm链接数据库都需要提前下载对应的驱动,自带的sqlite3对日期格式数据不敏感,如果后续业务需要使用日期辅助筛选数据那么不推荐使用sqlite3

    搭建方式

    1. 任意创建一个py文件,在该文件内书写固定的配置
    import os
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day06.settings")
        import django
        django.setup()
    
    1. 直接使用pycharm提供的python console

    image

    ORM 创建表

    # Mysql配置
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'orm_simple',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': 'root',
            'PASSWORD': 'root',
            'CHARSET':'utf8'
        }
    }
    '''__init__.py'''
    import pymysql
    pymysql.install_as_MySQLdb()
    

    创建表

    from django.db import models
    
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5,decimal_places=2)
        publish = models.CharField(max_length=32)
        publish_data = models.DateField()  # 出版时间
    
    # 路由
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('book/', views.book),
    ]
    
    

    ORM 添加数据

    有两种添加数据的方式:

    • 方式一:模型类实例化对象
    • 方式二:通过 ORM 提供的 objects 提供的方法 create 来实现(推荐)
    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    def book(request):
        '''添加数据的两种方式'''
        # 方式1
        book_obj = models.Book(title='Python',price='99',publish='Hammer出版社',publish_data='2022-2-2')
        book_obj.save()
        # 方式2    
        models.Book.objects.create(title='Java',price='88',publish='Hans出版社',publish_data='2021-2-1')
        return HttpResponse('<p>数据添加成功</p>')
    

    ORM 查询数据

    all 查询#

    all()方法查询所有数据,返回一个QuerySet对象,类似list,可以通过索引来获取列表中的对象,这里不支持负索引

    from django.shortcuts import render,HttpResponse
    from app01 import models
    
    def book(request):
        book_obj = models.Book.objects.all()
        print(book_obj)   # <QuerySet [<Book: Book object (1)>, <Book: Book object (2)>]>
        print(book_obj[0])   # Book object (1)
        print(book_obj.first())  # Book object (1) 等价于[0]
        print(book_obj.first().title) # Python 获取值
        return HttpResponse('<p>数据查询成功</p>')
    

    filter 查询#

    filter() 方法用于查询符合条件的数据

    返回的是 QuerySet 类型数据,类似于 list,里面放的是满足条件的模型类的对象,可用索引下标取出模型类的对象;

    def book(request):
        book_obj = models.Book.objects.filter(pk=2)
        print(book_obj)
        print(book_obj.first().title)  # JavaScript
        book_obj1 = models.Book.objects.filter(title='JavaScript',price='99')
        print(book_obj1.first().pk)  # 2
        return HttpResponse('<p>数据查询成功</p>')
    

    exclude 取反查询#

    exclude() 方法用于查询不符合条件的数据,返回的是 QuerySet 类型数据,类似于 list,里面放的是不满足条件的模型类的对象,可用索引下标取出模型类的对象;

    def book(request):
        book_obj = models.Book.objects.exclude(pk=2)
        print(book_obj)  # <QuerySet [<Book: Python>, <Book: C>, <Book: PHP>, <Book: C++>, <Book: 数据结构>]>
        for i in book_obj.all():
            print(i.title)  # Python C  PHP C++ 数据结构
        return HttpResponse('<p>数据查询成功</p>')
    

    get 查询#

    get() 方法用于查询符合条件的返回模型类的对象符合条件的对象只能为一个,如果符合筛选条件的对象超过了一个或者没有一个都会抛出错误

    区别filter()如果获取不到符合条件的数据,返回一个空对象,不报错

    from django.shortcuts import render,HttpResponse
    
    from app01 import models
    def book(request):
        book_obj = models.Book.objects.get(pk=1)
        print(book_obj)
        return HttpResponse('<p>数据查询成功</p>')
    

    order_by 排序#

    order_by() 方法用于对查询结果进行排序,返回的是 QuerySet类型数据,类似于list,里面放的是排序后的模型类的对象,可用索引下标取出模型类的对象

    • 参数的字段名要加引号
    • 降序为在字段前面加个负号 -
    def book(request):
        # 升序排序
        book_obj = models.Book.objects.order_by('id')
        for i in book_obj:
            print(i.title)  # Python  JavaScript C PHP C++ 数据结构
        # 降序排序
        book_obj1 = models.Book.objects.order_by('-id')
        for i in book_obj1:
            print(i.title)  # 数据结构 C++ PHP C JavaScript Python 
        return HttpResponse('<p>数据查询成功</p>')
    

    reverse 反转#

    reverse() 方法用于对查询结果进行反转,返回的是 QuerySe t类型数据,类似于 list,里面放的是反转后的模型类的对象,可用索引下标取出模型类的对象

    使用反转函数前先排序

    def book(request):
        # 按照价格升序排列:降序再反转
        books = models.Book.objects.order_by("-price").reverse()
        return HttpResponse("<p>查找成功!</p>")
    

    count 汇总数量#

    count() 方法用于查询数据的数量返回的数据是整数

    def book(request):
        book_obj = models.Book.objects.count()
        print(book_obj) # 查询所有数据的数量>>>6
        book_obj1 = models.Book.objects.filter(price=200).count() # 查询符合条件数据的数量
        return HttpResponse('<p>数据查询成功</p>')
    

    exists 判断#

    exists() 方法用于判断查询的结果 QuerySet 列表里是否有数据,返回的数据类型是布尔,有为 true,没有为 false。

    from django.shortcuts import render,HttpResponse
    from app01 import models
    def book(request):
        books = models.Book.objects.exists()
      	# True
        books = models.Book.objects.count().exists()
         # 报错,判断的数据类型只能为QuerySet类型数据,不能为整型
        books = models.Book.objects.first().exists()  
         # 报错,判断的数据类型只能为QuerySet类型数据,不能为模型类对象
        return HttpResponse("<p>查找成功!</p>")
    

    values 查询字段#

    返回的是 QuerySet 类型数据,类似于 list,里面不是模型类的对象,而是一个可迭代的字典序列,字典里的键是字段,值是数据

    def book(request):
        book_obj = models.Book.objects.values('price','title')
        print(book_obj)  # 返回所有price和title字段,以列表套字典的形式
        # <QuerySet [{'price': Decimal('99.00'), 'title': 'Python'}]
        book_obj1 = models.Book.objects.filter(pk=1).values('title')
        print(book_obj1,book_obj[0].get('title'))  # <QuerySet [{'title': 'Python'}]>  Python
        return HttpResponse('<p>数据查询成功</p>')
    

    values_list 查询部分字段#

    values_list() 方法用于查询部分字段的数据,values_list() 方法用于查询部分字段的数据

    def book(request):
        book_obj = models.Book.objects.values_list('price','title')
        print(book_obj)  # 返回所有price和title字段,以列表套元组的形式
        # <QuerySet [(Decimal('99.00'), 'Python')]
        for title in book_obj:
            print(title[1]) # 获取所有title
        return HttpResponse('<p>数据查询成功</p>')
    

    values和values_list区别

    • values查询返回的结果是列表套字典的形式,字段名和数据都能够获取到
    • values_list查询返回的结果是列表套元组的形式,只返回数据

    distinct 去重#

    distinct() 方法用于对数据进行去重,返回的是 QuerySet 类型数据

    注意:

    • 对模型类的对象去重没有意义,因为每个对象都是一个不一样的存在(主键不一样),去重的前提是数据必须是一模一样,不能加主键,有unique的也没意义
    • distinct() 一般是联合 values 或者 values_list 使用
    from django.shortcuts import render,HttpResponse
    from app01 import models
    def book(request):
        # 查询一共有多少个出版社
        books = models.Book.objects.values_list("publish").distinct() # 可以去重
        books = models.Book.objects.distinct()
        # 对模型类的对象去重没有意义,因为每个对象都是一个不一样的存在,主键不一样
        return HttpResponse("<p>查找成功!</p>")
    

    ORM 双下划线方法

    __in#

    类似sql的成员运算,用于读取区间,= 号后面为列表

    注意:filter 中运算符号只能使用等于号 = ,不能使用大于号 > ,小于号 < ,等等其他符号

    • 格式:字段__in = [a,b]
    def book(request):
        book_obj = models.Book.objects.filter(price__in=[100,300])
        print(book_obj)  # <QuerySet [<Book: Book object (2)>, <Book: Book object (22)>]>
        return HttpResponse('<p>数据查询成功</p>')
    

    __gt __gte#

    大于、大于等于

    # 价格大于100的数据
    book_obj = models.Book.objects.filter(price__gt=100)
    # 价格大于等于100的数据
    book_obj = models.Book.objects.filter(price__gte=100)
    

    __lt __lte#

    小于、小于等于

    # 价格小于100的数据
    book_obj = models.Book.objects.filter(price__lt=100)
    # 价格小于等于100的数据
    book_obj = models.Book.objects.filter(price__lte=100)
    

    __range#

    表示范围,在···之间,类似sql的between··and,左闭右区间,= 号后面为两个元素的列表

    # 价格在100到200之间的数据
    book_obj = models.Book.objects.filter(price__range=[100,300])
    

    __contains#

    包含关系,=号后面为字符串,类似sql的模糊查询,LIKE

    # 查询包含Py字符的书名
    book_obj = models.Book.objects.filter(title__contains='Py')
    

    __icontains#

    不区分大小写,和contains一样

    # 查询包含Py字符的书名
    book_obj = models.Book.objects.filter(title__contains='py')
    

    __startswith#

    查询以指定字符开头,= 号后面为字符串

    book_obj = models.Book.objects.filter(title__startswith='P')
    

    __endswith#

    查询以指定字符结尾,=号后面为字符串

    book_obj = models.Book.objects.filter(title__endswith='构')
    

    __year#

    __year 是 DateField 数据类型的年份,= 号后面为数字

    # 2022年出版的数据
    book_obj = models.Book.objects.filter(publish_date__year=2022)
    

    __month#

    查询月份

    # 3月出版的数据
    book_obj = models.Book.objects.filter(publish_date__month=3)
    

    __day#

    __day 是DateField 数据类型的天数,= 号后面为数字

    # 所有17号出版的数据
    book_obj = models.Book.objects.filter(publish_date__day=17)
    

    ORM 删除数据

    方式一:使用模型类的 对象.delete()

    返回值:元组,第一个元素为受影响的行数

    book_obj=models.Book.objects.filter(pk=8).first().delete()
    

    方式二:使用 QuerySet 类型数据.delete()(推荐)

    返回值:元组,第一个元素为受影响的行数。

    books=models.Book.objects.filter(pk__in=[1,2]).delete()
    

    注意:

    • Django 删除数据时,会模仿 SQL约束 ON DELETE CASCADE 的行为,也就是删除一个对象时也会删除与它相关联的外键对象;
    • delete() 方法是 QuerySet 数据类型的方法,但并不适用于 Manager 本身。也就是想要删除所有数据,不能不写 all;

    ORM 修改数据

    方式一:

    模型类的对象.属性 = 更改的属性值
    模型类的对象.save()
    
    def book(request):
        book_obj = models.Book.objects.filter(pk=23).first()
        print(book_obj)
        book_obj.title='如何傍富婆,从入门到入赘'
        book_obj.save()
        return HttpResponse('<p>入赘成功</p>')
    

    方式二:QuerySet 类型数据.update(字段名=更改的数据)(推荐)

    返回值:整数,受影响的行数

    def book(request):
        book_obj = models.Book.objects.filter(pk=23).update(title='人活一口气,打死不入赘')
        return HttpResponse(book_obj) # 1
    

    ORM 逆转到 SQL

    方式一:

    如果想打印orm转换过程中的sql,需要在settings中进行如下配置:

    '''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',
            },
        }
    }
    

    ps:本质是日志的监控,可以在test下测试

    方式二:使用对象.query获取原生SQL()

    from app01 import models
    res = models.Book.objects.filter(pk=2)
    print(res.query)
    
    '''
    SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`publish`, `app01_book`.`publish_date` FROM `app01_book` WHERE `app01_book`.`id` = 2
    '''
    
  • 相关阅读:
    2023年【汽车驾驶员(中级)】报名考试及汽车驾驶员(中级)证考试
    C++入门篇(命名空间和C++中输出输入的介绍)
    经典网络学习-ResNet代码实现
    Kafka(三)、Kafka架构
    BZOJ4756 Promotion Counting(线段树合并)
    C语言习题练习8--二进制&操作符
    基于springboot实现滴答拍摄影项目【项目源码+论文说明】
    2021年全球最具吸引力的雇主:谷歌、微软、苹果占据前三名
    reduceByKey(func, [numTasks]) 案例介绍_大数据培训
    英语语法汇总(12.倒装句)
  • 原文地址:https://www.cnblogs.com/48xz/p/15957340.html