Django之ORM
Django之ORM
object relational mapping 对象关系映射。
简单来说就是用面向对象的方式,描述数据库,表达数据库,操作数据库,达到不便携sql语句,就可以对数据库进行增删改查。
django内置了一套ORM,它的映射关系是:
类实例 ---------> 表中的一条记录
然后通过对类,类属性,类实例的各种操作,达到操作数据库的功能,底层是生成原生的sql进行数据操作。
安装数据库
我们项目选择使用MariaDB数据库,它是MySQL的一个分支,开源免费,越来越多的web项目开始使用它。直接安装数据库相对麻烦和难以维护,推荐使用docker安装数据库。安装docker的方案如下:
方案一
windows直接安装Docker Desktop,不推荐,个人感觉还是很影响系统的使用,且需要开启虚拟服务,会与某些软件冲突。
mac可以直接安装Docker Desktop。
方案二
windows系统,安装虚拟机,然后安装linux的虚拟机,再到虚拟机中安装docker环境。
虚拟机软件有,virtualbox(免费开源),vimware(收费),安装简单,使用稍复杂,资源占用大。
用过虚拟机的童靴可以选择此方案,从来没用过的可以忽略。
mac不建议。
方案三
买一台云服务器,在云服务器中安装docker。
阿里云,百度云,腾讯云,华为云,都有新用户优惠,几十块钱一年,推荐使用。
最后项目的部署也会使用云服务器。
阿里云新人优惠连接
注意:系统选择ubuntu
或者centos
。
创建数据库的docker命令
docker run --name ck10_mariadb --restart=always -d -v ck10_mariadb:/var/lib/mysql -e MARIADB_ROOT_PASSWORD=pythonvip -p 4002:3306 -e MARIADB_DATABASE=lemontest mariadb:latest
docker 入门教程 http://testingpai.com/article/1631792673644
django配置数据库
安装驱动
mysql,mariadb,django官方推荐的驱动程序mysqlclient
。
windows环境
在网站https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
下载与python版本对应的mysqlclient
本地安装文件,再使用pip命令安装,例如:
pip install mysqlclient‑1.4.6‑cp38‑cp38‑win_amd64.whl # py3.8 64位
mac环境
依赖mysql客户端
$ brew install mysql-client
$ echo 'export PATH="/usr/local/opt/mysql-client/bin:$PATH"' >> ~/.bash_profile
$ source .bash_profile
$ pip install mysqlclient
#使用 pycharm过程中 新建应用时出现了,驱动与django版本不兼容的问题
python manage.py startapp crm
报错内容如下:
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?
解决方法:在 “项目” 的__init__.py
文件中加上以下代码即可搞定
(前提是要先安装pymysql库)pip install pymysql
import pymysql
pymysql.version_info = (1, 3, 13, "final", 0)
pymysql.install_as_MySQLdb()
Linux环境
linux环境下需要对应的依赖,根据环境不同依赖有所不同,下面的只是基本的步骤,不能保证在所有的环境上都有效。
Debian/Ubuntu
$ sudo apt-get install python3-dev default-libmysqlclient-dev build-essential
$ pip install mysqlclient
Red Hat /CentOS
sudo yum install python3-devel mysql-devel
pip install mysqlclient
连接配置
在settings.py中修改如下配置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'lemontest',
'USER': 'root',
'PASSWORD': 'pythonvip',
'HOST': 'www.hhxpython.com',
'PORT': '4002'
}
}
注意: 如果实在是安装不好mariadb的环境,直接使用默认的sqlite数据库也可。
模型
django中的模型准确且唯一的描述了数据。它包含存储数据的重要的字段和行为。一般来说,每一个模型都映射一个张数据库表。
基础:
- 每个模型都是一个python的类,这些类都要继承
django.db.models.Model
- 模型类的每个属性都相当于数据库的一个字段
- 利用这些,Django提供了一个自动生成访问数据库的API
创建模型
设计一张学生表tb_student
,表结构如下:
id int not null auto_increment primarykey
name varchar(20) not null
age tinyint default null
sex tinyint default null
qq varchar(20) default null unique
phone varchar(20) defautl null unique
c_time datetime not null
跟视图一样,django中模型一般定义在应用目录下的models.py
模块下:
# crm/models.py
from django.db import models
class Student(models.Model): # 必须继承
# id int not null auto_increment primarykey
# name varchar(20) not null
# age tinyint default null
# sex tinyint default 1
# qq varchar(20) default null unique
# phone varchar(20) defautl null unique
# c_time datetime not null
name = models.CharField('姓名', max_length=20, help_text='姓名')
age = models.SmallIntegerField('年龄', null=True, blank=True, help_text='年龄')
sex = models.SmallIntegerField('性别', default=1, help_text='性别')
qq = models.CharField('qq号码', max_length=20, null=True, blank=True, unique=True, help_text='qq号码')
phone = models.CharField('手机号码', max_length=20, null=True, blank=True, unique=True, help_text='手机号码')
c_time = models.DateTimeField('创建时间', auto_now_add=True)
class Meta:
db_table = 'tb_student' # 设置创建表示的表名
verbose_name = '学生信息'
verbose_name_plural = verbose_name # django admin中显示模型的说明
字段类型
每一个字段由一个字段类的实例表示。每个字段实例的名称,类属性名,就是字段的名称,数据库也会以它为列名。
更多字段类型见官方文档
字段选项
每一个字段都会有一些参数,对应数据库中字段的各种属性。
常用的字段选项:
- primary_key: 指定是否主键,如果没有指定,django会自动创建主键。
- unique:
- null
- blank
- default
- auto_now=True每次修改的时候会自动更新时间
- auto_add_now=True 创建时自动添加时间
https://docs.djangoproject.com/zh-hans/3.2/ref/models/fields/#field-options
激活模型
安装应用
把应用添加到项目中,在配置文件中设置:
INSTALLED_APPS = [
...
'crm.apps.CrmConfig'
]
生成迁移记录
在命令行运行如下命令:
python manage.py makemigrations crm
会在应用的migrations
目录下生成迁移记录文件。
通过运行makemigrations
命令,django会检测你对模型文件的修改(修改了模型,修改了字段),并把修改的部分存储为一次迁移。
数据迁移
django有一个自动执行数据库迁移并同步管理数据库结构的命令migrate
。
通过命令sqlmigrate
可以看到你要迁移的sql。
python manage.py sqlmigrate crm 0001
那么就会输出对应迁移文件要执行的sql。
运行命令
python manage.py migrate
第一次迁移时,django会在数据库中创建一个特殊的表django_migrations
用来记录和跟踪执行过哪些迁移。
改变模型的时候需要三步:
- 编辑models.py文件,改变模型
- 运行
python mange.py makemigrations
为模型的改变生成迁移文件 - 运行
python mange.py migrate
应用数据库迁移
数据增删改查
django会自动给予一条数据库抽象API。
为了方便调试,我们通过下面的命令进入交互式python命令行:
python mange.py shell
这个命令会导入当前项目的django环境。
默认的python解释器,没有补全和高亮功能,推荐安装ipython
pip install ipython
增
In [1]: from crm.models import Student
In [2]: Student.objects.all()
Out[2]: <QuerySet []>
# 1.
In [3]: s = Student(name="心蓝")
In [4]: s.save()
In [5]: from django.db import connection
# 查看sql,只有调试模式才可以
In [6]: connection.queries
Out[6]:
[{'sql': "\n SELECT VERSION(),\n @@sql_mode,\n @@default_stor
age_engine,\n @@sql_auto_is_null,\n @@lower_case_table_names,\n
CONVERT_TZ('2001-01-01 01:00:00', 'UTC', 'UTC') IS NOT NULL\n ",
'time': '0.015'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED',
'time': '0.016'},
{'sql': 'SELECT `tb_student`.`id`, `tb_student`.`name`, `tb_student`.`age`, `tb_student`.`sex`, `tb_student`.`qq`, `tb_
student`.`phone`, `tb_student`.`c_time` FROM `tb_student` LIMIT 21',
'time': '0.015'},
{'sql': "INSERT INTO `tb_student` (`name`, `age`, `sex`, `qq`, `phone`, `c_time`) VALUES ('心蓝', NULL, 1, NULL, NULL,
'2022-01-14 13:41:45.978140') RETURNING `tb_student`.`id`",
'time': '0.016'}]
# 2
In [7]: s2 = Student()
In [8]: s2.name = "王五"
In [9]: s2.save()
In [10]: connection.queries[-1]
Out[10]:
{'sql': "INSERT INTO `tb_student` (`name`, `age`, `sex`, `qq`, `phone`, `c_time`) VALUES ('王五', NULL, 1, NULL, NULL, '
2022-01-14 13:44:07.792240') RETURNING `tb_student`.`id`",
'time': '0.015'}
# 3
In [11]: Student.objects.create(name='赵六',age=18)
Out[11]: <Student: Student object (3)>
# 4.
In [12]: Student.objects.get_or_create(name='心蓝')
Out[12]: (<Student: Student object (1)>, False)
In [13]: Student.objects.get_or_create(name='钱四')
Out[13]: (<Student: Student object (4)>, True)
查
# 查所有
In [14]: Student.objects.all()
Out[14]: <QuerySet [<Student: Student object (1)>, <Student: Student object (2)>, <Student: Student object (3)>, <Studen
t: Student object (4)>]>
# 查第一条
In [15]: Student.objects.first()
Out[15]: <Student: Student object (1)>
# 查主键=1的那一条
In [16]: Student.objects.get(pk=1)
Out[16]: <Student: Student object (1)>
<Student: Student object (1)>不是对象的一个方便的,可用的表示形式。通过去编辑模型,增加一个__str__
的方法。
# 条件查询
In [4]: Student.objects.filter(name='心蓝')
Out[4]: <QuerySet [<Student: 心蓝>]>
In [5]: Student.objects.filter(sex=1)
Out[5]: <QuerySet [<Student: 心蓝>, <Student: 王五>, <Student: 赵六>, <Student: 钱四>]>
改
# 获取对象,修改对象属性,然后再save
In [6]: s = Student.objects.first()
In [7]: s
Out[7]: <Student: 心蓝>
In [8]: s.age = 18
In [9]: s.save()
# 通过调用update可以批量修改,慎用
In [10]: Student.objects.filter(sex=1).update(age=19)
Out[10]: 4
删
在对象上调用delete方法即可。
In [15]: s
Out[15]: <Student: 心蓝>
In [16]: s.delete()
Out[16]: (1, {'crm.Student': 1})
In [17]: connection.queries[-1]
Out[17]:
{'sql': 'DELETE FROM `tb_student` WHERE `tb_student`.`id` IN (1)',
'time': '0.015'}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)