1.Django 的 ORM 介绍
ORM:对象关系映射 (英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。
作用:在实际开发中不方便直接对数据库进行sql语句操作,所以我们将sql数据库中的表,直接映射成python中的对象,对对象进行增删改查的操作。
2.数据库配置
- 安装
pymysql
pip install pymysql -i https://pypi.douban.com/simple
- 修改项目目录下的
__init__.py
文件
import pymysql
pymysql.install_as_MySQLdb()
- 手动创建一个当前项目的空的数据库,准备一个有创建数据库权限的用户
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.29 sec)
mysql> create database crm charset=utf8;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| crm |
| mydb |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
- 配置
settings.py
文件
DATABASES = {
'default': {
##定义引擎 'ENGINE': 'django.db.backends.sqlite3', ## python默认的小型文件数据库
##定义文件 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.mysql', ## 定义mysql引擎
'NAME': 'crm', ## 数据库名
'USER': 'admin',
'PASSWORD': 'Root110qwe',
'HOST':'127.0.0.1',
'PORT':'3306',
}
}
3.模型的创建与映射
模型:什么是模型,模型就是django.db.models.Model
的一个子类
模型类对应数据库中的数据表,类属性对应的表字段名
a.创建模型
- 模型定义在app文件夹下的
models.py
文件中
from django.db import models
# Create your models here.
class Students (models.Model): # 一个类代表一个数据表
id = models.AutoField(primary_key=True) ##创建一个可以自动生成的主键,这条也可以不写,Django中会自动生成主键
name = models.CharField(verbose_name='姓名',
max_length=20) ##创建字符类型字段,最大长度为20,设置提示信息'姓名'
### max_length为CharField的必须参数
age = models.SmallIntegerField(verbose_name='年龄',null=True) ##创建值可以为null的小整型字段,
sex = models.SmallIntegerField(default=1) ##创建缺省值为1的小整型字段
qq = models.CharField(max_length=20,null=True)
phone = models.CharField(max_length=20,null=True)
c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True) ##创建日期时间类型字段,自动创建当前时间
b.激活模型
- 注册应用
- 创建迁移
什么叫迁移:"在django中对数据库中的结构有任何改变都叫做迁移"
- 这条命令会在app目录的
migrations
目录下创建一个迁移文件
(crm) pyvip@VIP:~/projects/crm$ python manage.py makemigrations teacher
Migrations for 'teacher':
teacher/migrations/0001_initial.py
- Create model Students
- 如果要看这个迁移文件会产生什么样的SQL语句,可以执行下面这条命令
(crm) pyvip@VIP:~/projects/crm$ python manage.py sqlmigrate teacher 0001
BEGIN;
--
-- Create model Students
--
CREATE TABLE `teacher_students` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(20) NOT NULL, `age` smallint NULL, `sex` smallint NOT NULL, `qq` varchar(20) NULL, `phone` varchar(20) NULL, `c_time` datetime(6) NOT NULL);
COMMIT;
- 执行迁移文件操作数据库,将对模型的改动应用到数据库(底层就是执行了SQL语句)
(crm) pyvip@VIP:~/projects/crm$ python manage.py migrate teacher
Operations to perform:
Apply all migrations: teacher
Running migrations:
Applying teacher.0001_initial... OK
查看所创建的表
mysql> show tables;
+-------------------+
| Tables_in_crm |
+-------------------+
| django_migrations |
| teacher_students |
+-------------------+
2 rows in set (0.00 sec)
teacher_students
就是刚才创建的数据表,表名 = appname_模型类
django_migrations
是所有的迁移记录数据表,里面记录了所有的迁移记录
python manage.py migrate appname 这条命令执行的操作:
- 在app中查找迁移文件,并且去
django_migrations
表中查找,如果有没有执行的迁移文件就去执行 - 执行迁移生成的SQL语句
- 如果成功,会在
django_migrations
表中增加一条记录
4.简单的数据的增删改查
在Django模型中,一个类代表一张数据表,一个类的实例代表一条数据
-
Django调试环境
(crm) pyvip@VIP:~/projects/crm$ python manage.py shell
Python 3.6.6 (default, Sep 12 2018, 18:26:19)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
-
增
增加有几种方法
a. 第一种方式
In [1]: from teacher.models import Students #导入这个类
In [2]: Students.objects.all() #查询这个数据表的所有数据
Out[2]: <QuerySet []> #当前数据为空
In [3]: s = Students() #创建这个类的实例,即一条数据
In [4]: s
Out[4]: <Students: Students object (None)> # 这条数据为空
In [5]: s.name = '小米' #为这条数据的一个字段赋值
In [6]: s.age = 18
In [7]: s.save() #每次赋值之后必须要保存,否则数据不会上传到数据库中
In [8]: Students.objects.all()
Out[8]: <QuerySet [<Students: Students object (1)>]> #查询到一条数据
然后在数据库中就能查询到这条数据
mysql> select * from teacher_students;
+----+--------+------+-----+------+-------+----------------------------+
| id | name | age | sex | qq | phone | c_time |
+----+--------+------+-----+------+-------+----------------------------+
| 1 | 小米 | 18 | 1 | NULL | NULL | 2019-03-27 18:17:46.167806 |
+----+--------+------+-----+------+-------+----------------------------+
1 row in set (0.00 sec)
b. 第二种方式
In [10]: stu = Students.objects.create(name='小李',age=22) #直接用create方法直接创建
In [11]: stu.name
Out[11]: '小李'
In [12]: stu.id
Out[12]: 3
-
删除
In [13]: stu.delete()
Out[13]: (1, {'teacher.Students': 1})
-
改
改一条数据
In [14]: stu.age = 33
In [15]: stu.save()
改所有的数据
In [27]: Students.objects.all().update(age=15)
Out[27]: 3
-
查询
查一条数据和所有的数据
In [16]: Students.objects.all() #查所有的数据
Out[16]: <QuerySet [<Students: Students object (1)>, <Students: Students object (2)>, <Students: Students object (4)>]>
In [17]: res = Students.objects.all()
In [18]: print(res.query)
SELECT `teacher_students`.`id`, `teacher_students`.`name`, `teacher_students`.`age`, `teacher_students`.`sex`, `teacher_students`.`qq`, `teacher_students`.`phone`, `teacher_students`.`c_time` FROM `teacher_students`
In [19]: Students.objects.get(pk=1) #查询主键为1的一条数据,如果查询到多条数据就报错,主键默认参数为`pk`
Out[19]: <Students: Students object (1)>
首先我们看一下这几条语句,什么是objects
,什么是QuerySet
,什么是all()
方法
-
objects
是一个Manager
类型的对象,定义在from django.db import models
中,是默认生成的,也就是objects = Modes.Manage()
,他提供一个数据库和模型对象交互的接口(api)。Students.objects.all()
翻译过来就是Students
类通过Manager
管理器,用all
接口返回一个QuerySet
对象
在res = Students.objects.get()或者res = Students.objects.all()中
- Students是类名,就是你在model中创建的类
- objects是django默认的管理器对象,帮你完成各种操作。
- get()或者all()是API,一种内置函数,不同的操作调用不同的API就可以了。
- res通过all()得到的就是queryset()对象,也就是查询对象的集合。
QuerySet是惰性的,只有调用的时候才会执行
带条件查询
In [25]: res = Students.objects.filter(name='小米',age=18)
In [26]: res
Out[26]: <QuerySet [<Students: Students object (1)>]>
补充:模型元数据
我们要定义模型的一些属性,比如排序选项(attr:~Options.ordering),数据库表名(db_table),或是人可读的单复数名(verbose_name和verbose_name_plural)时,必须要用到元数据,内部使用Meta类来给模型赋予元型态数据
实例:
from django.db import models
class Ox(models.Model):
horn_length = models.IntegerField()
class Meta:
ordering = ["horn_length"] #默认按horn_length字段的升序排序
verbose_name_plural = "oxen" #设置模型对象的复数名称