Six, orm of single-table operation Django

Django model layer (a) single-table operation

A, ORM

ORM is "object - relational - mapping" for short. (Object Relational Mapping, referred to as ORM)

orm fact, the grammar-translation engine class object into a sql statement

Class object --- sql

Class - Table

Object - Line

Properties - field

Comparative native sql orm codes and Python:

Two, Django database connection

In app application Django project, there is a models.py file, and is designed to write database-related code

  1. models.py file under app01 applications, write code to create a table
    from django.db import models

    # 创建表
    class Userinfo(models.Model):
    
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=18)
        age = models.IntegerField()
        current_date = models.DateField()
    
    # 相当于:
    # create table userinfo(
    #   id int primary key auto_increment,
    #   name vachar(18),
    #   age int,
    #   current_data date
    # );
  2. Not connected mysql, the default connection is sqlite database, document database is a small, test time can be about, but rarely used in actual production, but with mysql
    use sqlite database:

    The first time you run it, because the driver is not installed sqlite is not open database

    After installing the drive on again, the following occurs is to run successfully, it shows the table structure of our production

    This time we can add the data

  3. Mysql connection
    found in the configuration settings in the file:
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': the os.path.join (base_dir, 'db.sqlite3'),
    }
    }

    # 修改成:
    # 现在终端创建一个库 orm01
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': '127.0.0.1',
            'POST': 3306,        #  端口 默认3306
            'NAME': 'orm01',
            'USER': 'root',
            'PASSWORD': '123',
    
        }
    }

    然后在项目文件夹下的 init.py 文件中加入这两句话:
    import pymysql
    pymysql.install_as_MySQLdb() # MySQLdb是默认的连接数据库的客户端模块,但是不支持Python3.4以上版本,所以要用pymysql把MySQLdb替换掉

    最后执行数据库同步指令
    python manage.py makemigrations
    python manage.py migrate

    进入cmd终端进入mysql查看我们的表是否插入进去了:

    由此可见,我们插入表的操作算是成功的完成了!!!

三、ORM表单操作

(一)、简单的增删改查

类---表
类对象 --- 一行数据
类属性 --- 字段

先创建一张表,定义四个属性:

class Student(models.Model):
    id =  models.AutoField(primary_key=True)
    name = models.CharField(max_length=18)
    age = models.IntegerField()
    birth_date = models.DateField()

  1. 创建记录的 方式一:

    def orm(request):
    student_obj = models.Student(
    name = 'jiege',
    age = 23,
    birth_date = '1995-01-27'
    )
    student_obj.save()
    return render(request,'myorm.html')

    创建记录的 方式二:

    两种方式
    一种 models.Student.objects.create(name='yuhao',...) # 关键字
    另一种 models.Student.objects.create(**{'name':'liangdao',....}) # 字典打散

    def orm(request):
    new_obj = models.Student.objects.create(name='yuhao',age=25,birth_date='1995-02-06')
    print(new_obj) # Student object -- model对象
    print(new_obj.name) # 点属性,可以获取对应字段的数据
    return render(request,'myorm.html')

     new_obj = models.Student.objects.create(**{'name':'liangdao','age':'25','birth_date':'1994-07-22'})
     print(new_obj)
     print(new_obj.name)
     return render(request,'myorm.html')

    创建记录的 方式三:(批量创建,bulk_create)

    def orm(request):
    obj_list = []
    for i in range(5):
    obj = models.Student(
    name=f'xiaobai{i}',
    age=i+1,
    birth_date='2000-01-01'
    )
    obj_list.append(obj)
    models.Student.objects.bulk_create(obj_list)
    return render(request,'myorm.html')

    创建记录的 方式四:(有就更新,没有就创建,update_or_create)

    def orm(request):
    models.Student.objects.update_or_create(
    name='baobao',
    age=23,
    birth_date='1995-03-15'
    )
    return render(request,'myorm.html')

    添加日期的数据,要注意:

    方式一:
    models.Student.objects.create(birth_date='1996-11-15') # 字符串的形式

    方式二:
    import datetime
    now_date = datetime.datetime.now()
    models.Student.objects.create(birth_date=now_date) # 此时插入的仍然是date类型,2019-7-19 这样

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

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

    .all方法 查询所有的数据 返回的是queryset集合

    all_objs = models.Student.objects.all()
    print(all_objs)
    # <QuerySet [<Student: Student object>, <Student: Student object>, <Student: Student object>]> -- 类似于列表 -- queryset集合

    all_objs = models.Student.objects.all()
    for i in all_objs:
    print(i.name)
    # jiege、yuhao.....,点属性可以取出对应的数据

    .filter方法 条件查询 返回的也是queryset集合,查询不到内容,不会报错,返回一个<QuerySet []>空的queryset

    objs = models.Student.objects.filter(id=2) # 找id为2的那条记录
    print(objs) # <QuerySet [<Student: Student object>]>

    objs1 = models.Student.objects.filter(name='dazhuang')
    print(objs1) # <QuerySet []> 没找到不报错,显示空

    objs = models.Student.objects.filter(id=2,name='yuhao')
    # 里面的多个条件用逗号分开,并且这几个条件必须都成立,是and的关系,or关系搞不定
    print(objs) # <QuerySet [<Student: Student object>]>

    .get方法 条件查询 返回的是model对象,而且get方法有且必须只有1个结果

    obj = models.Student.objects.get(id=3) # 找id为3的那条记录
    print(obj) # model对象,Student object
    print(obj.name) # 点属性,可以取出对应的数据,liangdao

  2. delete方法,queryset 和model对象都可以调用

    models.Student.objects.get(id=13).delete() # model对象来调用的delete方法

    models.Student.objects.filter(age=1).delete() # queryset调用的delete方法

    models.Student.objects.all().delete() # 删除所有

  3. update方法,

只能queryset调用

model对象不能调用更新方法 报错信息'Student' object has no attribute 'update'

models.Student.objects.get(name='jiege').update(age=28)
# .get()返回的是model对象,不能调用update方法,会报错

models.Student.objects.filter(name='jiege').update(age=28)
# .filter()返回的是queryset对象,可以调用update方法

(二)、查询接口

  • all() 查所有
    查询所有结果,结果是queryset类型

  • filter(**kwargs) 条件查询
    它包含了与所给筛选条件相匹配的对象,结果也是queryset类型
    models.Student.objects.filter(id=2,name='yuhao')
    # 里面的多个条件用逗号分开,并且这几个条件必须都成立,是and的关系,or关系搞不定

    models.Student.objects.filter(**{'id':2,'name':'yuhao'})
    # 打散形式传参
  • get(**kwargs) 条件查询
    返回与所给筛选条件相匹配的对象,不是queryset类型,是行记录对象,也就是model对象,返回结果有且只有一个,
    如果符合筛选条件的对象超过一个或者没有都会抛出错误。捕获异常try。

  • exclude(**kwargs) 排除
    排除的意思,它包含了与所给筛选条件不匹配的对象,没有不等于的操作昂,用这个exclude,返回值是queryset类型

    objects控制器和queryset集合都可以调用exclude,返回结果是queryset类型
    
    # objects控制器调用(objects后直接加exclude方法):
      query = models.Student.objects.exclude(id=1)
      print(query) # 找到除了id是1的数据
    
    # queryset集合调用
      query = models.Student.objects.filter(age=38).exclude(id=6)
      print(query) # 找到age是38,除了id是6的数据
  • order_by(*field) 排序
    queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,返回值还是queryset类型

    objs = models.Student.objects.all().order_by('age')
    # 默认是按照升序排列的,也就是按照age的升序排列
    
    objs = models.Student.objects.all().order_by('age','id')
    # 多条件的,逗号隔开,先按照age升序排列,在age相同的情况下,按id升序排列
    
    objs = models.Student.objects.all().order_by('age','-id')
    # 降序排列,加一个'-'就可以
  • reverse() 反转
    queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型

    # 用在排序之后反转
    query = models.Student.objects.all().order_by('age').reverse()
    print(query)
  • count() 计数
    queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量。

    objs = models.Student.objects.all().count()
    print(objs)
  • first() 第一条记录
    queryset类型的数据来调用,返回第一条记录,得到的都是model对象,不是queryset

    obj = models.Student.objects.all().first()
    print(obj)
  • last() 最后一条记录
    queryset类型的数据来调用,返回最后一条记录,结果为model对象类型

    obj1 = models.Student.objects.all().last()
    print(obj1)
  • exists() 判断是否包含查的数据,返回True或False
    queryset类型的数据来调用,如果QuerySet包含数据,就返回True,否则返回False

    空的queryset类型数据也有布尔值True和False,但是一般不用它来判断数据库里面是不是有数据,如果有大量的数据,你用它来判断,那么就需要查询出所有的数据,效率太差了,用count或者exits
    
    例:all_books = models.Book.objects.all().exists() 
    # 翻译成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,就是通过limit 1,取一条来看看是不是有数据
  • values(*field) 用的比较多 返回一个字典序列
    queryset类型的数据来调用,返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。

    obj = models.Student.objects.filter(age=25).values()
    print(obj)
    # <QuerySet [{'id': 2, 'name': 'yuhao', 'age': 25, 'birth_date': datetime.date(1995, 2, 6)}, {'id': 3, 'name': 'liangdao', 'age': 25, 'birth_date': datetime.date(1994, 7, 22)}]>
    
    obj = models.Student.objects.filter(age=25).values('name','age')
    print(obj)
    # <QuerySet [{'id': 2, 'name': 'yuhao', 'age': 25}, {'id': 3, 'name': 'liangdao', 'age': 25 }]>
  • values_list(*field) 返回一个元组序列
    它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

    obj = models.Student.objects.filter(age=25).values_list('name','age')
    print(obj)
    # <QuerySet [('yuhao', 25), ('liangdao', 25)]>
  • distinct() 去重
    values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复纪录,结果还是queryset

    query = models.Student.objects.all().values('age').distinct()
    print(query)

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

1. __in=[]  值等于列表里任意一个的对象
    obj = models.Student.objects.filter(age__in=[22,25,28])
    print(obj)
    # <QuerySet [<Student: jiege>, <Student: yuhao>, <Student: liangdao>, <Student: zhumo>]>
    
2. __gt  大于   __gte  大于等于
    obj = models.Student.objects.filter(age__gt=25)
    print(obj)
    # <QuerySet [<Student: jiege>]>
    # 注意,别写age>25,这种参数不支持
    
3. __lt  小于   __lte  小于等于

4. __range=[]  值在一个范围内
    obj = models.Student.objects.filter(age__range=[22,25])
    print(obj)
    # sql的between and,大于等于22,小于等于25
    
5. __contains  包含
    obj = models.Student.objects.filter(name__contains='xiao')
    print(obj)
    # name中包含xiao的
    
6. __icontains 包含,不区分大小写
    obj = models.Student.objects.filter(name__contains='xiao')
    print(obj)
    # name中包含xiao的,不区分大小写,比如Xiao这种也能识别出来
    
7.  __startswith  以什么开头   __endswith  以什么结尾

8. __year  找日期年份相关的   __month 月份
    obj = models.Student.objects.filter(birth_date__year='1995')
    print(obj)
    # 找生日是1995年的人
    
    obj1 = models.Student.objects.filter(birth_date__year='1995',birth_date__month='01')
    print(obj1)
    # 找生日是1995年1月份的人

.

Guess you like

Origin www.cnblogs.com/yangzm/p/11221109.html