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用来记录和跟踪执行过哪些迁移。

改变模型的时候需要三步:

  1. 编辑models.py文件,改变模型
  2. 运行python mange.py makemigrations 为模型的改变生成迁移文件
  3. 运行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'}
posted @   夜久听山雨  阅读(84)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示