• Django:ORM单表操作


      ORM,实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖特定的数据库,通过简单的配置,就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变动而导致的无效劳动

    ORM是 对象-关系-映射 的简称:object relational mapping

    类对象--->sql---->pymysql---->mysql服务端---->磁盘,ORM就是将类对象的语法翻译成sql语句的一个引擎

    原生sql和python的orm代码对比

    #sql中创建表
    create table empluyee(
        id int primary key auto_increment,
        name varchar(20),
        gender bit default 1,
        birthday data,
        department varchar(10),
        salary decimal(8,2) unsigned,
    )
    # 添加表记录
    insert employee (name,gender,birthday,salary,department) values ('alex',1,'1977-12-12',4000,'cleaning');
    
    #查询表记录
    select * from employee where name='alex';
    
    #更新表记录
    update employee set birthday='1966-01-01' where name='alex';
    
    #删除表记录
    delete from employee where name='alex';
    
    #Django中models.py
    class Employee(models.Model):
        id = models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        gender=models.BooleanField()
        birthday=models.DateField()
        department=models.CharField(max_length=32)
        salary=models.DecimalField(max_digits=8,decimal_places=2)
    #python的类对象
    emp=Employee(name='alex',gender=True,birthday='1981-01-01',department='cleaning')
    emp.save()
    #查询一条表记录
    Employee.objects.filter(age=24)
    #更新一条表记录
    Employee.objects.filter(id=1).update(birthday='1982-02-02')
    #删除一条表记录
    Employee.objects.filter(id=1).delete()

    在pycharm用连接mysql

    1.在项目settings.py中修改DATABASES
        DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST':'127.0.0.1',            
            'PORT':3306,
            'NAME':'ormtest',    # 要连接的mysql库名
            'USER':'root',
            'PASSWORD':'123456',
            }
        }
    2.在项目__init__.py中
        import pymysql
        # MySQLdb()是Django用来连接mysql数据的工具,这里用pymysql代替MySQLdb
        pymysql.install_as_MySQLdb()
    
    3.在应用文件夹中models.py中写入创建数据的类
        class UserInfo(models.Model):
        #create table userinfo(id int primary key auto_increment,
        # name varchar(16),age int,current_date date)
            id = models.AutoField(primary_key=True)
            name = models.CharField(max_length=16)
            age = models.IntegerField()
            current_date = models.DateField()
    
    4.在命令行(Terminal)中输入命令
        python manage.py makemigrations    # 创建一条记录,数据库操作的记录
        python manage.py migrate        # 连接数据库,并按model.py中写类来生成表,以及生成django自带的表

    外部文件使用models.py

    在Django中可以用外部的py文件操作models.py,来操作数据库
    1.在项目下创建 xx.py文件,写入代码
    # 外部文件使用jdango的models,需要配置jdango环境
    
    import os
    
    if __name__ == '__main__':
        os.enveron.setdefault("DJANGO_SETTINGS_MODULE","ormhw.settings")
        import django                                #  项目名称  settings.py
        django.setup()
        from app01 import models
        
        obj_lst = []
        
        for i in range(1,10):
            obj = models.Books(
                title = 'python%s'%i,
                price = 120+i,
                pub_date = '101%s-10-10'%i,
                publish = 'beida' if i<5 else 'tsinghua'
            )
            obj_lst.append(obj)
        models.Books.objects.bulk_create(obj_lst)
    2.直接运行xx.py 文件,就可以执行代码,对数据库做操作

    Django项目通过浏览器admin后台管理数据库

    # 在app 中的admin.py中添加需要管理的类,即创建的表
    from django.contrib import admin
    from app01 import models
    # Register your models here.
    
    admin.site.register(models.Book)
    
    #在pycharm terminal中输入命令
    python manage.py createsuperuser
    
    #接着输入username/password,email可以不用输入,直接回车
    
    #运行项目,在浏览器上输入127.0.0.1:8000/admin
    #输入用户名密码即可管理添加的数据库表了

    数据库相关字段

    '''
    1.CharField    
        字符串字段,必须要有一个参数:max_length
    2.IntergerField  
        保存一个整数
    3.DecimalField   
        一个浮点数,必须提供两个参数:max_digits 总位数,decimal_places 小数位数
    4.AutoField     
        表示一个自增字段
    5.BooleanField  
        A true/false field.admin 用 checkbox 来表示此类字段
    6.TextField
        一个容量很大的文本字段
        admin用一个<textarea>表示该字段数据
    7.EmailField
        一个带有检查Email合法性的 CharField,不接受  max_length参数
    8.DateField
        日期字段,有下列额外的可选参数
        Argument    描述
        auto_now    对象被保存时,自动将该字段的值设置为当前时间,通常用于表现通常用于表示 "last-modified" 时间戳.
        auto_now_add  当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
            (仅仅在admin中有意义...)
    9.DateTimeField
        时间字段,类似DateField支持同样的附加选项
    10.ImageField
        类似FileField,不过要校验上传对象是否是一个合法图片,它有两个可选参数:height_field和width_field,如果提供这两个参数,则图片将按提供的高度和宽度规格保存. 
    11.FileField
        文件上传字段
        必须要有的参数:upload_to,用于保存上传文件的本地文件系统路径。这个路径必须包含 strftime #formatting,该格式将被上载文件的 date/time
         替换(so that uploaded files don't fill up the given directory).
         admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件)
    12.URLField
        用于保存URL,若verify_exists参数为True,给定的URL会预先检查是否存在( 即URL是否被有效装入且
          没有返回404响应).
        admin用一个<input type='text'>文本框表示该字段保存的数据
    13.NullBooleanField
        类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项
        admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据.
    14.SlugField
    15.XMLField
        一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema #的文件系统路径.
    16.FilePathField
    17.IPAaddressField
        一个字符串形式的 IP 地址, (i.e. "24.124.1.30").
    '''

    更多的参数

    '''
    1.null
        如果为True ,Django将用NULL来在数据库存储空值,默认值是false
    2.blank
        如果为True,该字段允许不添,默认为false
        这与null不同,null纯粹是数据库范畴的,blank是数据验证范畴的
        如果一个字段blank=True,表单的验证将允许该字段为空值,如果blank=false,该字段就必须有值
    3.default
        字段的默认值,可以是一个值或者可调用对象。如果可调用,每有新对象被创建它都会被调用,如果你的字段没有设置为可以为空,那么将来如果我们后添加一个字段,这个字段就要给一个default值
        
    4.primary_key
        如果为True,那么这个字段就是模型的主键。如果没有指定任何一个字段的primary_key=True,Django就会自动添加一个IntegerField字段作为主键,所以除非你想覆盖默认的主键行为,否则抹油必要设置一个字段的primary_key=True
    
    5.unique
        如果设置值为True,这个数据字段的值在整张表中必须是唯一的
    
    6.choices
        由二元组组成一个可迭代对象,用来给字段提供选择项。如果设置choices,默认的表单将是一个选择框而不是标准的文本框,而且这个选择框的选项就是choices中的选项
        
    7.db_index
        如果db_index=True,则代表将此字段设置为数据库索引
        
    8.DatetimeField  DateField  TimeField 这三个时间段,都可以设置如下属性
        auto_now_add
            配置auto_now_add=True,创建数据记录的时候,会把当前时间添加到数据库
        auto_now
            配置auto_now=True,每次更新数据记录都会跟新该字段,标识这条记录的最后一次的修改时间
        
        
    '''

    ORM字段与mysql数据库实际字段的对应关系

    'AutoField': 'integer AUTO_INCREMENT',
        'BigAutoField': 'bigint AUTO_INCREMENT',
        'BinaryField': 'longblob',
        'BooleanField': 'bool',
        'CharField': 'varchar(%(max_length)s)',
        'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
        'DateField': 'date',
        'DateTimeField': 'datetime',
        'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
        'DurationField': 'bigint',
        'FileField': 'varchar(%(max_length)s)',
        'FilePathField': 'varchar(%(max_length)s)',
        'FloatField': 'double precision',
        'IntegerField': 'integer',
        'BigIntegerField': 'bigint',
        'IPAddressField': 'char(15)',
        'GenericIPAddressField': 'char(39)',
        'NullBooleanField': 'bool',
        'OneToOneField': 'integer',
        'PositiveIntegerField': 'integer UNSIGNED',
        'PositiveSmallIntegerField': 'smallint UNSIGNED',
        'SlugField': 'varchar(%(max_length)s)',
        'SmallIntegerField': 'smallint',
        'TextField': 'longtext',
        'TimeField': 'time',
        'UUIDField': 'char(32)',

    添加表记录

    python中 orm 的对应关系有三种

    类 ----------------->表

    类对象------------->行(表记录)

    类属性------------->表字段

    首先想要操作表的增删改查,需要先导入这个表

    # views.py中导入需要操作的表
    from app01 import models
    
    def index(request):
        '''
        添加表记录,等数据库操作
        '''
        obj=models.Book(title='python',price='120',pubdate='2019-10-10',publish='人民出版社')
        obj.save()
        
        
    # create 方法插入数据,返回的是object对象
        obj=models.Book。objects.create(title='python',price='120',pubdate='2019-10-10',publish='人民出版社')
        print(obj.title)
    
        
    # 批量创建
        objs = []
        for i in range(20):
            obj = models.UserInfo(
                name='alex%s'%i,
                age = 20 + i,
                current_date='1990-01-01'
            )
             objs.append(obj)
        models.UserInfo.objects.bulk_create(objs)
        
    
    # 创建方法:updata_or_create,有就更新,没有就创建
        models.UserInfo.objects.update_or_create(
            name='wusir111',
            defaults={
                'age':35,
                'current_date':'1982-03-03'
            }
        )

    查询表记录

    # 简单查询,获取所有对象,即表记录以对象的形式返回,queryset
    all_objs = models.UserInfo.objects.all()
    print(all_objs) #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>
        for obj in all_objs:
            print(obj.name)
            
    # filter(**kwargs) 条件查询,查询不到内容,不会报错,返回空 queryest
        objs = models.UserInfo.objects.filter(id=1)
        print(objs) # <QuerySet [<UserInfo: aliex>]>
    
        objs1 = models.UserInfo.objects.filter(name = 'wusir')
        print(objs1)    # <QuerySet [<UserInfo: wusir>]>
        
    # get(**kwargs),返回的是model对象,有且只有一个结果。如果没有会报错,有多条记录也会报错
        obj = models.UserInfo.objects.get(id = 3)
        print(obj)  # aliex
         
        # obj = models.UserInfo.objects.get(name='jackma')
        # print(obj)  # 查询记录有多条或者没有的时候报错 get() returned more than one UserInfo -- it returned 2!
        
    # order_by(*field) queryset类型的数据来调用,对查询的结果排序,默认按照id来升序的,返回值还是queryset类型
        query = models.UserInfo.objects.all().order_by('age','-id')
        print(query)  # 按照age从小到大排序,age相同的记录按照id 从大到小排序
    
    # reverse()   queryset类型的数据调用,对返回结果进行反向排序,返回值还是queryset类型
        query = models.UserInfo.objects.all().order_by('id').reverse()
        print(query)  # 返回queryset类型
        
    # count()     queryset类型的数据调用,返回数据库中匹配查询到的数量
        num = models.UserInfo.objects.all().count()
        print(num)
        
    # first()     queryset类型的数据调用,返回第一条记录,得到的是model对象
    # first()     queryset类型的数据调用,返回最后一条记录,得到的是model对象
        fobj = models.UserInfo.objects.all().first()
        lobj = models.UserInfo.objects.all().last()
        
    # exists()    queryset类型的数据调用,如果queryset包含数据,则返回True,否则返回False
        obj = models.UserInfo.objects.filter(id=50).exists()
        print(obj)
        
     # values 返回queryset类型数据,元素是dick类型
        query = models.UserInfo.objects.filter(id__gt=25).values()   # 查询id>25的结果
        print(query)  #<QuerySet [{'id': 26, 'name': 'wusir111', 'age': 35, 'current_date': datetime.date(1982, 3, 3)}]>
        
    # value_list  返回queryset类型数据,元素列表里面套元祖
        query = models.UserInfo.objects.filter(id__gt=25).values_list()   # 查询id>25的结果
        print(query)    # <QuerySet [(26, 'wusir111', 35, datetime.date(1982, 3, 3))]>
        
    #distinct 去重,values 和 values_list 得到的queryset类型的数据来调用

    基于双下划线的模糊查询

    Book.objects.filter(price_in=[110,220,210]) # 查询price值等于这三个里面任意一个的对象,返回所有符合条件的对象
    Book.objects.filter(price_gt=100)    # price大于100的对象。大于等于price_gte
    Book.objects.filter(price_lt=100)    # price小于100的对象。小于等于price_lte
    Book.objects.filter(price_range=[100,200])#相当于sql 的between and,大于等于100,小于等于200
    Book.objects.filter(title_contains='python')# title中包含python的
    Book.objects.filter(title_icontains='python')# 不区分大小写
    Book.objects.filter(title_startswith='py')# 以什么开头,不区分大小写
    Book.objects.filter(pub_date__year=2012)
    
    all_books=models.Book.objects.filter(pub_date__year=2012)# 找2012年所有的书
    all_books=models.Book.objecs.filter(pub_date__year__gt=2012)#找大于2012年所有的书籍

    删除表记录

    # delete()方法的调用者可以是一个model对象,也可以是一个queryset集合。它立即执行删除对象,没有返回值
    
    obj.delete()
    
    # 也可以一次删除多个对象,每个Queryset都有一个delete方法,它一次性删除queryset中的所有对象
    models.Book.objects.filter(pub_date__year=2012).delete()#删除2015年的所有书籍
    
        models.UserInfo.objects.get(id=3).delete()  # 删除id=3 的记录
        models.UserInfo.objects.filter(name='jackma').delete()  # 删除 name='jackma'的所有记录
        models.UserInfo.objects.all().delete()  # 删除所有

    修改表记录

    # 更新 update()方法,model对象不能调用更新方法,只能queryset调用
       models.UserInfo.objects.filter(name='wusir').update(age=3)

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

  • 相关阅读:
    Java:前程似锦的 NIO 2.0
    优秀的程序员都热爱写作
    Java -- JDBC 学习--获取数据库链接
    前端学习 -- Html&Css -- 条件Hack 和属性Hack
    前端学习 -- Html&Css -- ie6 png 背景问题
    前端学习 -- Html&Css -- 框架集
    ECMAScript 6 -- 字符串的扩展
    ECMAScript 6 -- 数组的解构赋值
    前端学习 -- Html&Css -- 表单
    前端学习 -- Html&Css -- 表格
  • 原文地址:https://www.cnblogs.com/jmuchen/p/13434022.html
Copyright © 2020-2023  润新知