zoukankan      html  css  js  c++  java
  • Django 07模型层—单表操作

    Django 模型层—单表操作

    一、数据库相关设置

    若想将模型转为mysql数据库中的表,需要在settings中配置

    # Mysql连接配置
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'lxx',
            'USER': 'root',
            'PASSWORD': '123',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'ATOMIC_REQUEST': True,
            'OPTIONS': {
                "init_command": "SET storage_engine=MyISAM",
            }
        }
    }
    '''
    'NAME':要连接的数据库,连接前需要创建好
    'USER':连接数据库的用户名
    'PASSWORD':连接数据库的密码
    'HOST':连接主机,默认本机
    'PORT':端口 默认3306
    'ATOMIC_REQUEST': True,
    设置为True统一个http请求对应的所有sql都放在一个事务中执行(要么所有都成功,要么所有都失败)。
    是全局性的配置, 如果要对某个http请求放水(然后自定义事务),可以用non_atomic_requests修饰器 
    'OPTIONS': {
                 "init_command": "SET storage_engine=MyISAM",
                }
    设置创建表的存储引擎为MyISAM,INNODB
    '''
    

    在models中通过类建立我们自己需要用的数据库表

    class User(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=16)
        age = models.IntegerField()
        birthday = models.DateField()
    

    注意1:NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建 USER和PASSWORD分别是数据库的用户名和密码。设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。然后,启动项目,会报错:no module named MySQLdb 。这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名文件下的__init__,在里面写入

    import pymysql
    pymysql.install_as_MySQLdb()
    

    最后通过两条数据库迁移命令即可在指定的数据库中创建表 :

    python manage.py makemigrations
    python manage.py migrate
    

    配置ORM的loggers日志(可以打印orm转换过程中的sql)

    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level': 'DEBUG',
            },
        }
    }
    

    在进行数据库的单表操作前需要导入一些相关模块,

    import os
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dg68_1.settings")
    
    # 直接导入django,可以查看并运用jdango包相关模块, 但无法使用用django创建的项目中的模块
    import django
    django.setup()
    
    # from django.db import models
    from appo.models import User
    

    二、简单的增删查改

    1、增

    ​ 方式一:

    user = User.objects.create(name='egon',age=18,birthday='2010-3-8')
    

    ​ 方式二:

    u1 = User(name='egon',age=18,birthday='2010-3-8')
    ul.save()
    

    2、查

    #操作结果拥有一个list
    u_list= User.objects.filter(name='egon')
    
    #只能操作有且仅有一条数据的记录
    try:
        u2 = User.objects.get(name="egon")
        print(u2)
    except Exception:
        print("egon 对象不唯一")
    

    3、改

    User.objects.filter(name='Owen').update(name='Owen_best')
    
    users = User.objects.filter(name='Owen_best')
    for user in users:
        user.name = 'Owen'
        user.save()
    

    4、删

    User.objects.filter(id=3).delete()
    
    u4 = User.objects.filter(id=1)[0]
    u4.delete()
    

    三、单表操作的函数

    <1> all():                  查询所有结果
    <2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
    <3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
    <4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
    <5> order_by(*field):       对查询结果排序('-id')
    <6> reverse():              对查询结果反向排序
    <8> count():                返回数据库中匹配查询(QuerySet)的对象数量。
    <9> first():                返回第一条记录
    <10> last():                返回最后一条记录
    <11> exists():              如果QuerySet包含数据,就返回True,否则返回False
    <12> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并							不是一系列,model的实例化对象,而是一个可迭代的字典序列
    <13> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的							是一个字典序列
    <14> distinct():            从返回结果中剔除重复纪录
    
    1. all():查询所有结果list,支持正向索引取值[i],支持索引切片[m:n]
    user_list = User.objects.all()
    print(type(user_list))
    print(user_list)
    QuerySet对象都有query属性,里面存放的的是得到该结果执行的sql语句(ORM内部还存在对sql语句的优化)
    print(user_list.query)
    
    支持正向所有(不支持反向索引,原因是数据过多时,不能将数据一次性查出,需要分批次按需求查出)
    u5 = User.objects.all()[0]
    print(u5)
    
    支持切片
    u_l1 = User.objects.all()[1:3]
    print(u_l1)
    print(u_l1.query)
    
    2. exclude(**kwargs):查询满足条件的对立面的所有结果list
    u_l2 = User.objects.exclude(id=1)
    print(u_l2)
    print(u_l2.query)
    
    3. order_by(*field):查询按照指定字段进行排序后的所有结果list,'tag_name'代表正序,'-tag_name'代表降序
    u_l3 = User.objects.order_by('-id')
    print(u_l3)
    print(u_l3.query)
    
    4. reverse():反转排序查询的所有结果list
    u_l4 = User.objects.order_by('id').reverse()
    print(u_l4)
    print(u_l4.query)
    
    5. count():统计返回查询结果list的长度
    count = User.objects.all().count()
    print(count)
    
    
    6. exists():判断查询结果是否存在,值为布尔类型
    res = User.objects.filter(id=10).exists()
    print(res)
    
    
    7. values(*field):按照指定字段(们)进行查询,返回存放包含字段(们)的字典的列表list
    u_l5_dic = User.objects.values('name', 'age')[1:3]
    # print(u_l5_dic.query)
    print(u_l5_dic)
    
    8. values_list(*field):同values类似,返回存放数据的元组的列表list
    u_l6_dic = User.objects.values_list('name', 'age')[1:3]  # [0][1] 第一个元组中的第二个数据,年龄
    print(u_l6_dic)
    
    9. distinct():从查询结果中剔除重复字段(一般和values结合使用)
    u_l7 = User.objects.values('name', 'age', 'birthday').distinct()
    print(u_l7)
    

    四、模糊查询(基于双下划线)

    u8 = User.objects.filter(id__exact=1)  # 就是id=1的精确查询
    print(u8)
    print(u8.query)
    
    # 整型相关
    age__exact=8  # 确切匹配8
    age__in=[8, 10]  # 8或10
    age__gt=8  # 大于8
    age__gte=8  # 大于等于8
    age__lt=8  # 小于8
    age__lte=8  # 小于等于8
    age__range=[8, 10]  # 8到10之间
    age__isnull=0|1  # 0:is not null | 1:is null
    
    # 字符串相关
    name__startswith  # 后方模糊匹配
    name__endswith  # 前方模糊匹配
    name__contains  # 前后方均模糊匹配
    name__regex  # 正则匹配
    name__istartswith  # 不区分大小写后方模糊匹配(i开头就是不区分大小写)
    
    # 时间相关
    birthday__year=2008  # 时间年份模糊匹配
    

    五、F查询(基于计算)

    from django.db.models import F
    案例一:将id为1的结果年龄增加1
    u10 = User.objects.filter(id=1).first()
    print(u10)
    u10.age += 1
    u10.save()
    
    
    User.objects.filter(id=1).update(age=age+1) # update不能完成二步操作
    User.objects.filter(id=1).update(age=F('age')+1)
    User.objects.filter(id=1).values('age')
    
    
    案例二:查询id是年龄1/20的结果
    res_list = User.objects.filter(id=F('age')/20)
    User.objects.values('age')
    print(res_list)
    

    六、Q查询

    from django.db.models import Q
    # &  |  ~
    u_l20 = User.objects.filter(name__iregex="xiaohou", age=18)  # 默认就是 与关系 &
    print(u_l20)
    
    # 需求:年纪<20 或 姓名包含a
    u_l21 = User.objects.filter(Q(age__lt=20) | Q(name__icontains='a'))
    print(u_l21)
    
    # 需求:年纪大于20
    u_l22 = User.objects.filter(~Q(age__lte=20))
    print(u_l22)
    

    补:

    删除表纪录

    删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如:

    model_obj.delete()
    

    你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。

    例如,下面的代码将删除 pub_date 是2005年的 Entry 对象:

    Entry.objects.filter(pub_date__year=2005).delete()
    

    在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如:

    b = Blog.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()
    

    要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

    Entry.objects.all().delete() 
    

    如果不想级联删除,可以设置为:

    pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)
    

    修改表纪录

    Book.objects.filter(title__startswith="py").update(price=120
    

    此外,update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数

  • 相关阅读:
    inner join ,left join ,right join 以及java时间转换
    华为机试-整形数组合并
    华为机试-公共字串计算
    两个字符串的最长公共子序列的长度
    华为机试-字符串通配符
    工作中总结的编程小技巧
    C语言高效编程的几招(绝对实用,绝对经典)
    Java float保留两位小数或多位小数
    新浪云、阿里云、百度云、谷歌云、亚马逊云
    java经典40+分析
  • 原文地址:https://www.cnblogs.com/prodigal/p/10483804.html
Copyright © 2011-2022 走看看