本文转载自https://blog.csdn.net/xiaogeldx/article/details/87899499
django的orm简介
- 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。
- orm的优势:用面向对象的方式描述数据库,操作数据库,不用直接编写sql代码,只需像操作对象一样从数据库操作数据
django的orm系统的分析
- orm系统的方法-(封装)-Python代码-(执行)-sql语句-(操作)-数据库
django模型映射关系
- 模型类必须都写在app下的models.py文件中
- 模型如果需要映射到数据库,所在的app必须被安装
- 一个数据表对应一个模型类,表中的字段对应模型中的类属性,一个实例对应数据表中的一条数据
数据库连接配置
- django不光支持mysql,一些流行的数据库都支持
django连接MySQL的配置流程
-
安装pymysql:pip install pymysql
-
创建数据库用户(有数据库权限的用户)
-
创建数据库(我的是django_test)
-
修改配置(settings.py)
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django_test', 'USER':'xiaoge', 'PASSWORD':'*****', 'HOST':'127.0.0.1', 'PORT':'****' } }
-
修改项目文件夹(和settings.py文件所在的目录)下的__init__.py添加代码:
import pymysql pymysql.install_as_MySQLdb()
-
设置时区(settings.py)
TIME_ZONE = 'Asia/ShangHai' #北京时间
模型的创建与映射
创建模型
-
创建一个student的模型,代表学生
-
每一个模型都是django.db.models.Model的子类
-
类变量表示模型中的数据库字段
-
每一个字段由一个字段类的实例表示
-
数据表的名称就是模型的名称
-
在students中的models.py文件中创建模型
from django.db import models class Student(models.Model): #继承 #可以不写主键,模型会创建 # id = models.IntegerField(primary_key=True,auto_created=True) name = models.CharField(max_length=20) #字符串 age = models.SmallIntegerField(default=0) #整数,默认为0,表示没填 sex = models.SmallIntegerField(default=1) #整数,默认为1(男) qq = models.CharField(max_length=20,default='') #字符串,默认不填 phone = models.CharField(max_length=20,default='') #字符串,默认不填 c_time = models.DateTimeField(verbose_name='创建时间',auto_now_add=True) #创建时间,自动记录当前时间 def __str__(self): return '%s-%s' % (self.name,self.age)
激活模型
-
在项目中注册app
- 在settings.py的INSTALLED_APPS中注册
-
运行数据库迁移命令(在项目根目录下)
python manage.py makemigrations students#如果不加students,settings.py的INSTALLED_APPS中所有的app都会迁移- 告诉django我们做了哪些数据库的修改
数据库迁移文件见下图的0001_initial.py,再修改就会多个0002
- python manage.py sqlmigrate students 0001可以从迁移的地方获取sql语句,效果见下图
- 表名:appname_模型name(小写的),如students_student
- django会自动创建主键,一般取名为id
- 告诉django我们做了哪些数据库的修改
-
此时数据库中还没有表,需要运行migrate命令使迁移生效
python manage.py migrate students
- 要修改数据库,都要修改模型,然后运行数据库迁移命令,再运行使迁移生效命令
数据的增删改查
-
django shell调试工具
python manage.py shell
-
导入模型
from students.models import Student
增
In [2]: Student.objects #模型管理器,每个模型都有一个管理器,通过管理器操作模型
Out[2]: <django.db.models.manager.Manager at 0x7f7b39787b00>
In [3]: Student.objects.all()
Out[3]: <QuerySet [ ]> #查询集
In [4]: s1 = Student(name='xiaoge',age=16,qq='234552') #增方法1
In [5]: Student.objects.all()
Out[5]: <QuerySet []> #此时还没有写进数据库
In [6]: s1.save() #经过这步才写进数据库
In [7]: Student.objects.all()
Out[7]: <QuerySet [<Student: Student object (1)>]>
In [11]: s2 = Student() #增方法2 11-14步 依次添加
In [12]: s2.name = 'na'
In [13]: s2.age = 17
In [14]: s2.save()
In [2]: Student.objects.all()
Out[2]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>]>
In [3]: s = Student.objects.get(id=1) #单条数据查看
In [4]: s.name
Out[4]: 'xiaoge'
In [5]: s.c_time
Out[5]: datetime.datetime(2019, 2, 24, 2, 6, 32, 247014, tzinfo=<UTC>)
In [6]: print(s.c_time)
2019-02-24 02:06:32.247014+00:00
In [7]: Student.objects.create(name='wen',age=25) #增方法3
Out[7]: <Student: wen-25>
In [8]: Student.objects.all()
Out[8]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>]>
In [9]: s = Student.objects.get_or_create(name='yi') #增方法4 查找或创建
In [10]: s
Out[10]: (<Student: yi-0>, True) #之前没有,新建成功 #返回元组
In [11]: s = Student.objects.get_or_create(name='wen')
In [12]: s
Out[12]: (<Student: wen-25>, False) #之前有,查到的,没新建
In [13]: s[0].name
Out[13]: 'wen'
In [14]: s[0].id
Out[14]: 3
- 在mysql中查看表
select * from students_student;
- 存在数据库里的时间(c_time)是UTC时间,取出时自动转换设置的时区
查
-
Student.objects.all()
-
Student.objects.get(pk=1)
-
Student.objects.filter(sex=1)
In [16]: res = Student.objects.all() #查1 这时不会操作数据库 In [15]: Student.objects.all() #这时查所有数据,返回QuerySet(查询集) Out[15]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>, <Student: yi-0>]> QuerySet是惰性的 In [17]: print(res.query) #Student.objects.all()背后执行的sql语句 SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time` FROM `students_student` #select * from students_student In [18]: res #查1 结合16步 返回一个查询集,可以for循环,迭代,切片 Out[18]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>, <Student: yi-0>]> In [19]: print(res[1:2].query) #切片 SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time` FROM `students_student` LIMIT 1 OFFSET 1 In [20]: Student.objects.get(id=1) # 查2 返回查询对象 Out[20]: <Student: xiaoge-16> In [21]: Student.objects.get(name='yi') #get一般和主键对应 Out[21]: <Student: yi-0> In [23]: Student.objects.get(pk=1) #pk即主键,防止查错主键名 Out[23]: <Student: xiaoge-16> In [25]: res = Student.objects.filter(sex=1) #查3 筛选 In [26]: res Out[26]: <QuerySet [<Student: xiaoge-16>, <Student: na-17>, <Student: wen-25>, <Student: yi-0>]> In [28]: print(res.query) SELECT `students_student`.`id`, `students_student`.`name`, `students_student`.`age`, `students_student`.`sex`, `students_student`.`qq`, `students_student`.`phone`, `students_student`.`c_time` FROM `students_student` WHERE `students_student`.`sex` = 1
当get匹配到多条数据时,会报错
改
In [30]: s = Student.objects.get(name='xiaoge')
In [31]: s
Out[31]: <Student: xiaoge-16>
In [32]: s.age = 15 #改方法1 改一条数据
In [33]: s.save()
In [34]: Student.objects.get(pk=1)
Out[34]: <Student: xiaoge-15>
In [35]: Student.objects.filter(name='yi').update(age=19) #改方法2 可以改多条数据
Out[35]: 1 #成功返回1
In [36]: Student.objects.get(name='yi')
Out[36]: <Student: yi-19>
删
In [38]: s = Student.objects.get(id=2) #删一条 38-40步
In [39]: s
Out[39]: <Student: na-17>
In [40]: s.delete()
Out[40]: (1, {'students.Student': 1})
In [41]: Student.objects.filter(gender=1).delete() #可以删多条
In [42]: Student.objects.filter(sex=1).delete()
Out[42]: (3, {'students.Student': 3})