1. ORM介绍
ORM概念
ORM(Object Relational Mapping),即对象关系映射。ORM是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。ORM在业务逻辑层和数据库层之间充当了桥梁的作用
ORM优势
ORM解决的主要问题是对象和关系的映射,通常把一个类和一个表一一对应,类的每个实例对象对应表中的一条记录,类的每个属性对应表中的每个字段。ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样来操作数据库,提高了开发效率
ORM劣势
ORM的缺点是会在一定程度上降低程序的执行效率
2. Django模型系统(Model)
-
在Django中model是数据单一、明确的信息来源,它包含了存储数据的字段和行为,Django中的模型就是python中的class类
-
每个类对应一个数据库中的表(类名即表名)
-
每个类中的属性对应数据库中的表字段(类属性即字段名)
-
每个类实例化的对象对应数据库表中的数据(类对象即数据)
-
ORM执行数据库操作的五个步骤:
-
手动创建数据库
-
在项目目录下的__init__.py文件中导入模块pymysql,并指定pymysql代替MySQLdb(django默认使用mysqldb连接组件,但是python3不支持mysqldb,需要修改默认的连接组件为pymysql)
-
在settings.py文件中配置数据库信息(django默认连接sqlite3,如果需要连接mysql,只需要修改配置中的ENGINE对应的值即可。django支持的数据库类型有:SQLite3、MySQL、Oracle、PostgreSQL)
-
在app的目录中的models.py文件中创建类和属性,每一个类必须继承models.Model这个类
-
给Django发送执行命令(在当前项目的目录下执行,运行命令前最好先启动Django项目)
-
先执行python manage.py makemigrations app (#在当前app的目录下创建migrations目录,并记录下所有的关于models.py文件的改动,只是做记录,并不会执行到数据库中。如果models.py文件中没有修改,会提示"No changes detected")
-
再执行python manage.py migrate app (#把migrations目录中文件的记录执行到数据库中)
-
ORM执行数据库操作的四个部分:
-
在models.py文件中创建类
-
Django把models.py文件中的类解析成sql语句
-
调用pymysql模块
-
通过pymysql把解析后的sql语句执行到mysql数据库
3. 简单使用ORM操作数据表
创建表
-- 手动创建数据库
create database day67 charset=utf8;
# 导入pymysql模块
import pymysql
pymysql.install_as_MySQLdb()
# 修改数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': 'localhost',
'PORT': 3306,
'USER': 'yy',
'PASSWORD': '123',
'NAME': 'day67',
'CHARSET': 'utf8'
}
}
# 创建类和属性
from django.db import models
# 打开models.py文件,会自动添加导入模块的这一行,创建app时django自动创建了models.py,这一行也是django自动添加的
# 常见的类名就是数据库的表名,ORM会自动转为小写
# 每一个实例化的对象名就是数据库表的字段名
# 默认情况下,创建的表名会把当前app的名称当成表前缀加上,如果在类中指定Meta类,并且指定db_table = '表名',则创建的表名就是db_table指定的值
# 除了创建的表以外,django还会自动创建一些表(anth_*、django_*)
class User(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
class Group(models.Model):
id = models.AutoField(primary_key=True)
g_name = models.CharField(max_length=50)
class LinkUG(models.Model):
id = models.AutoField(primary_key=True)
g_id = models.IntegerField()
u_id = models.IntegerField()
class Meta:
db_table = 'user_group'
# 登记记录
python manage.py makemigrations app1
# 执行到数据库
python manage.py migrate app1
# 查看数据库结果
use day67;
show tables;
>>>
+----------------------------+
| Tables_in_day67 |
+----------------------------+
| app1_group |
| app1_user |
| 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 |
| user_group |
+----------------------------+
# 再次添加一张表
class Level(models.Model):
id = models.AutoField(primary_key=True)
l_name = models.CharField(max_length=50)
python manage.py makemigrations app1
python manage.py migrate app1
show tables;
+----------------------------+
| Tables_in_day67 |
+----------------------------+
| app1_group |
| app1_level |
| app1_user |
| 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 |
| user_group |
+----------------------------+
修改表名
# 直接修改类名就是修改表名
class UserInfo(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
python manage.py makemigrations app1
# 执行登记记录之后会有提示确认信息
python manage.py migrate app1
show tables;
+----------------------------+
| Tables_in_day67 |
+----------------------------+
| app1_group |
| app1_level |
| app1_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 |
| user_group |
+----------------------------+
添加表字段
class UserInfo(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
pwd = models.CharField(max_length=50)
python manage.py makemigrations app1
python manage.py migrate app1
# 查看修改之前的表结构
desc app1_userinfo;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
# 查看修改之后的表结构
desc app1_userinfo;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
| pwd | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
修改表字段
class UserInfo(models.Model):
id = models.AutoField(primary_key=True)
username = models.CharField(max_length=20)
password = models.CharField(max_length=50, default='123456')
sex = models.IntegerField(null=True)
email = models.CharField(max_length=50, null=True)
python manage.py makemigrations app1
python manage.py migrate app1
desc app1_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| password | varchar(50) | NO | | NULL | |
| email | varchar(50) | YES | | NULL | |
| sex | int(11) | YES | | NULL | |
| username | varchar(20) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
删除表字段
# 一般情况下不会删除字段,可以把需要删除的字段对应类中的属性注释即可
class UserInfo(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
password = models.CharField(max_length=50, null=True)
# sex = models.IntegerField(null=True)
# email = models.CharField(max_length=50, null=True)
python manage.py makemigrations app1
python manage.py migrate app1
desc app1_userinfo;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(255) | NO | | NULL | |
| password | varchar(50) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
4. 简单使用ORM操作表数据
操作数据的视图写在views.py文件中,需要导入模型models.py文件才能使用模型的类
from . import models
查询数据
-
all():获取所有数据,每一条数据对象存储在列表中
# 获取所有数据的对象列表
all_data = models.表名.objects.all()
>>>
# 使用索引下表的方式获取字段值
print(all_data[1].字段名)
# 使用循环遍历的方式获取字段值
for i in all_data:
print(i.字段名)
# 获取第一条数据的字段值
print(all_data.first().字段名)
# 获取最后一条数据的字段值
print(all_data.last().字段名)
-
get():根据指定条件获取单条数据,如果数据不存在会报错
models.表名.objects.get(字段名='字段值')
-
filter():根据指定条件获取数据,每一条符合条件的数据对象存储在列表中
# filter查询出符合条件的数据对象存储在列表中,获取每一个对象的属性值的方法跟all()方法一样
models.表名.objects.filter(字段名='字段值')
-
exclude():根据去除指定条件获取数据,对指定的条件进行取反,每一条不符合条件的数据对象存储在列表中
# exclude查询出不符合条件的数据对象存储在列表中,获取每一个对象的属性值的方法跟all()方法一样
models.表名.objects.exclude(字段名='字段值')
添加数据
models.表名.objects.create(字段名1='字段值1', 字段名2='字段值2')
add_obj = models.表名(字段名1='字段值1', 字段名2='字段值2')
add_obj.save()
-
指定的参数是键值对的类型添加的,可以使用字典的形式传入,传入的字典需要解包(**kwargs)
dic = {'字段名1': '字段值1', '字段名2': '字段值2'}
# 方法一
models.表名.objects.create(**dic)
# 方法二
add_obj = models.表名(**dic)
add_obj.save()
删除数据
删除数据的原理是先查询到符合条件的数据,再执行删除操作。不管查询到符合条件的数据有多少条,都会直接删除
models.表名.objects.filter(字段名='字段值').delete()
修改数据
修改数据的原理是先查询到符合条件的数据,再执行修改操作。
-
方法一:直接创建对象并修改到数据库中,不用管查询到符合条件的数据有多少条,直接全部修改
models.表名.objects.filter(查找的字段名='查找的字段值').update(修改的字段名='修改的字段值')
-
方法二:先根据需要查找的条件实例化对象,然后根据修改的字段名修改数据。此时查找到符合条件的数据可能是一条或多条,返回的对象是以列表的形式存储,需要使用循环遍历的方法来修改
alt_obj = models.表名.objects.filter(查找的字段名='查找的字段值')
for i in alt_obj:
i.修改的字段名 = '修改的字段值'
i.save()