三、Django ORM基础

一、Django ORM介绍

ORM是什么?:(在django中,根据代码中的类自动生成数据库的表也叫–code first)

Django中内嵌了ORM框架,不需要直接编写SQL语句进行数据库操作,而是通过定义模型类,操作模型类来完成对数据库中表的增删改查和创建等操作。

ORM:Object Relational Mapping(关系对象映射)

  • 对数据库的表进行操作(新建,删除,更新等)
  • 对表中的数据(每一条数据)进行操作(增删改查)
    在这里插入图片描述

ORM的优点

数据模型类都在一个地方定义,更容易更新和维护,也利于重用代码。

ORM 有现成的工具,很多功能都可以自动完成,比如数据消除、预处理、事务等等。

它迫使你使用 MVC 架构,ORM 就是天然的 Model,最终使代码更清晰。

基于 ORM 的业务代码比较简单,代码量少,语义性好,容易理解。

新手对于复杂业务容易写出性能不佳的 SQL,有了ORM不必编写复杂的SQL语句, 只需要通过操作模型对象即可同步修改数据表中的数据.

开发中应用ORM将来如果要切换数据库.只需要切换ORM底层对接数据库的驱动【修改配置文件的连接地址即可】

ORM缺点

ORM 库不是轻量级工具,需要花很多精力学习和设置,甚至不同的框架,会存在不同操作的ORM。
对于复杂的业务查询,ORM表达起来比原生的SQL要更加困难和复杂。
ORM操作数据库的性能要比使用原生的SQL差。
ORM 抽象掉了数据库层,开发者无法了解底层的数据库操作,也无法定制一些特殊的 SQL。【自己使用pymysql另外操作即可,用了ORM并不表示当前项目不能使用别的数据库操作工具了。】

二、安装使用

安装mysqlclient

pip install mysqlclient

在这里插入图片描述

设置需要连接的数据库

编辑全局配置文件settings.py文件

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',    ###不通数据库类使用不同的后端引擎
        'NAME': 'django',   ###需要连接的数据库,需要提前创建
        'USER': 'root',  ###连接时使用的用户名
        'PASSWORD': 'root',  ###连接时使用的密码
        'HOST': 'localhost',   ###数据库ip
        'PORT': '3306',     ###数据库端口

    }
}


##########################
如果默认所有的app都使用default的数据库,
如果要每个app都使用一个数据库,可将“default”的名字改成各自的app名字即可。

创建表

编辑app01中的models.py文件

class UserInfo(models.Model):   ##创建一个类
    name = models.CharField(max_length=32)  ###添加的字段名称以及字段类型为字符
    password = models.CharField(max_length=64)
    age = models.IntegerField()  ###字段类型为整数
    
模型类如果未指明表名db_table,Django默认以 小写app应用名_小写模型类名 为数据库表名。
   #   class Meta:
#        db_table = 'db_study'     ####修改表的名称为db_study

字段类型如下:

类型说明
AutoField自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
BooleanField布尔字段,值为True或False
NullBooleanField支持Null、True、False三种值
CharField字符串,参数max_length表示最大字符个数,对应mysql中的varchar
TextField大文本字段,一般大段文本(超过4000个字符)才使用。
IntegerField整数
DecimalField十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数,常用于表示分数和价格 Decimal(max_digits=7, decimal_places=2) ==> 99999.99~ 0.00
FloatField浮点数
DateField日期参数auto_now表示每次保存对象时,自动设置该字段为当前时间。参数auto_now_add表示当对象第一次被创建时自动设置当前。参数auto_now_add和auto_now是相互排斥的,一起使用会发生错误。
TimeField时间,参数同DateField
DateTimeField日期时间,参数同DateField
FileField上传文件字段,django在文件字段中内置了文件上传保存类, django可以通过模型的字段存储自动保存上传文件, 但是, 在数据库中本质上保存的仅仅是文件在项目中的存储路径!!
ImageField继承于FileField,对上传的内容进行校验,确保是有效的图片

执行命令创建表

python manage.py makemigrations    ###生成迁移文件
python manage.py migrate           ###同步数据库

在这里插入图片描述
查看数据库表结构

MariaDB [django]> show tables;
+----------------------------+
| Tables_in_django           |
+----------------------------+
| app01_userinfo             |   ###为创建的表名称
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.01 sec)
##########################
MariaDB [django]> desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| name     | varchar(32) | NO   |     | NULL    |                |
| password | varchar(64) | NO   |     | NULL    |                |
| age      | int(11)     | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
#########orm会自动添加id字段,并且设置为主键,auto

###djaogo orm创建表时,读取的是注册的app的。按照app的注册顺序创建表

在这里插入图片描述

三、操作表

新增表

新建一个类即可

class UserInfo(models.Model):

    name = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    age = models.IntegerField()

class deployment(models.Model):    ###添加deployment表

    name = models.CharField(max_length=32)
    
再次执行  
python manage.py makemigrations
python manage.py migrate

在这里插入图片描述
查看数据库

MariaDB [django]> show tables;
+----------------------------+
| Tables_in_django           |
+----------------------------+
| app01_deployment           |    ###增加了app01_deployment表
| app01_userinfo             |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
12 rows in set (0.00 sec)

MariaDB [django]> 

删除表

删除deployment类,注释掉即可
在这里插入图片描述
执行以下命令查看

python manage.py makemigrations
python manage.py migrate

在这里插入图片描述
查看数据库,表app01_deployment已经被删除了

MariaDB [django]> show tables;
+----------------------------+
| Tables_in_django           |
+----------------------------+
| app01_userinfo             |
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
11 rows in set (0.01 sec)

修改表

class study(models.Model):
    name = models.CharField(max_length=32)
    six = models.CharField(max_length=32)
    age = models.CharField(max_length=32)
    height = models.IntegerField
    class Meta:
        db_table = 'db_study'     ####修改表的名称为db_study

在全局setings.py文件中添加如下内容,可以看到orm转换sql的过程

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

四、新增/删除字段

添加字段

添加size字段,需要设置默认值,或者指定字段可为空

class UserInfo(models.Model):

    name = models.CharField(max_length=32)
    password = models.CharField(max_length=64)
    age = models.IntegerField()
    size = models.IntegerField(default=2)      ###设置默认值为2,或者(null=True,blank=True)

如下所示:
在这里插入图片描述

MariaDB [django]> desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| name     | varchar(32) | NO   |     | NULL    |                |
| password | varchar(64) | NO   |     | NULL    |                |
| age      | int(11)     | NO   |     | NULL    |                |
| size     | int(11)     | NO   |     | NULL    |                |  ##新增了size字段
+----------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

如果不设置默认值或者允许为空,否则会出现以下问题
在这里插入图片描述
在这里插入图片描述

删除字段

删除size字段

MariaDB [django]> desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| name     | varchar(32) | NO   |     | NULL    |                |
| password | varchar(64) | NO   |     | NULL    |                |
| age      | int(11)     | NO   |     | NULL    |                |
| size     | int(11)     | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

注释models.py文件中的size皆可
在这里插入图片描述
查看表,size字段已经被删除。

MariaDB [django]> desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| name     | varchar(32) | NO   |     | NULL    |                |
| password | varchar(64) | NO   |     | NULL    |                |
| age      | int(11)     | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

五、数据的增删改查

全局urls.py中增加orm的path,如下:

from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('orm/',views.orm)    ####添加路由规则
]

编辑app01中views.py文件,添加orm函数,如下:

from django.shortcuts import render,HttpResponse,redirect
from app01.models import UserInfo
def orm(request):
    ####创建名称为的用户
    UserInfo.objects.create(name="lisa",password="123",age="11")

    return HttpResponse("成功")

界面访问并查看数据库,如下:
在这里插入图片描述

查看数据

MariaDB [django]> select * from app01_userinfo;
+----+------+----------+-----+
| id | name | password | age |
+----+------+----------+-----+
| 19 | lisa | 123      |  11 |
+----+------+----------+-----+
1 row in set (0.01 sec)

MariaDB [django]> 

查看orm转换sql的过程
在这里插入图片描述

删除

编辑app01中views.py文件,添加orm函数,如下:

def orm(request):
    ####删除用户
    UserInfo.objects.filter(name="lisa").delete()  ###删除指定条件查询得到的结果
    ####删除所有
#    UserInfo.objects.all().delete()   ###删除表中所有数据

    return HttpResponse("成功")

更新

编辑app01中views.py文件,添加orm函数,如下:

def orm(request):
    ###更新用户数据
    UserInfo.objects.filter(name="lisa").update(name="tom",age=22)
    return HttpResponse("成功")

查看orm转换sql的过程
在这里插入图片描述
查看数据库,结果已经改变

MariaDB [django]> select * from app01_userinfo;
+----+------+----------+-----+
| id | name | password | age |
+----+------+----------+-----+
| 19 | tom  | 123      |  22 |
+----+------+----------+-----+
1 row in set (0.01 sec)

查找

查看所有数据
def orm(request):

    ###查找用户,返回的QuerySet数据
    data_list = UserInfo.objects.all()
    print(data_list)
    return HttpResponse("成功")

查看返回结果
在这里插入图片描述
数据库中有4条记录,返回的QuerySet中4个对象数据

查询具体的返回值

def orm(request):
    ###查找用户
    data_list = UserInfo.objects.all()

    for item in data_list:
        print(item.name,item.id,item.password,item.age)
    return HttpResponse("成功")

查看返回结果
在这里插入图片描述

根据条件查找
def orm(request):

    ###查找用户,返回的QuerySet数据
    data_list = UserInfo.objects.filter(name="tom")
    #data_list = UserInfo.objects.valuesr("name")    ###查询某个字段
    print(data_list)
    return HttpResponse("成功")

查看返回结果
在这里插入图片描述

get方法查找
def orm(request):
    ####get方式获取的是模型数据,可以直接使用句点符获取数据
    ####此方式只适合查找只有一条记录的数据     
    data_list = UserInfo.objects.get(name="tom")
    #data_list = UserInfo.objects.get(name="tom").id
    print(data_list.id,data_list.name,data_list.password)
    return HttpResponse("成功")

在这里插入图片描述

first、last查找
def orm(request):
    ###查看第一条记录
    data_list = UserInfo.objects.all().first()
    print(data_list.age,data_list.id,data_list.name)
    return HttpResponse("成功")
MariaDB [django]> select * from app01_userinfo;
+----+-------+----------+-----+
| id | name  | password | age |
+----+-------+----------+-----+
| 19 | tom   | 123      |  22 |
| 20 | lisa  | 123      |  11 |
| 21 | david | 123      |  33 |
| 22 | kaka  | 123      |  33 |
+----+-------+----------+-----+
4 rows in set (0.00 sec)

MariaDB [django]>

在这里插入图片描述

查看最后一条记录
MariaDB [django]> select * from app01_userinfo;
+----+-------+----------+-----+
| id | name  | password | age |
+----+-------+----------+-----+
| 19 | tom   | 123      |  22 |
| 20 | lisa  | 123      |  11 |
| 21 | david | 123      |  33 |
| 22 | kaka  | 123      |  33 |
+----+-------+----------+-----+
4 rows in set (0.00 sec)

在这里插入图片描述

反向查询exclude

筛选条件不匹配的对象,返回queryset对象。

def stuinfo(request):
    ##查询不满足结果的数据
    students = stu.objects.exclude(name="张三")
    print(students)
    return HttpResponse("查询成功")
排序order_by

对查询的结果进行排序

def stuinfo(request):
    ###对结果进行排序
    students = stu.objects.all().order_by("-age")  ##按照大小排序
    print(students)
    return HttpResponse("查询成功")
查询某个数据的数量
def stuinfo(request):
    ##查询某个属性的个数
    students = stu.objects.filter(sex=1).count()
    print(students)      ###返回的是一个数字
    return HttpResponse("查询成功")
values()
value()把结果集中的模型对象转换成字典,并可以设置转换的字段列表,达到减少内存损耗,提高性能
def stuinfo(request):
     ###只查询某几个字段(结果返回的是字典)
    values = stu.objects.all().values("name", "age")
    print(values)

返回结果如下:
在这里插入图片描述

values_list()
values_list(): 把结果集中的模型对象转换成列表,并可以设置转换的字段列表(元祖),达到减少内存损耗,提高性能
def stuinfo(request):
     ###只查询某几个字段(结果返回的是字典)
    values = stu.objects.all().values_list("name", "age")
    print(values)

在这里插入图片描述

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值