目录
一、ORM简介
对象关系映射(Object Relational Mapping),它的实质就是将关系数据(库)中的业务数据用对象的形式表示出来,并通过面向对象(Object-Oriented)的方式将这些对象组织起来,实现系统业务逻辑的过程。
在ORM过程中最重要的概念是映射(Mapping),通过这种映射可以使业务对象与数据库分离。从面向对象来说,数据库不应该和业务逻辑绑定到一起,
ORM则起到这样的分离作用,使数据库层透明,开发人员真正的面向对象。
映射(Mapping) —— 把表结构映射成类
对象 —— 像操作类对象一样,操作数据库里的数据
优点:
- 实现了代码与数据操作的解耦合
- 不需自己写原生sql, 提高开发效率
- 防止SQL注入, 通过对象操作的方式,默认就是防止sql注入的。
缺点:
- 牺牲性能, 对象到原生SQL势必会有转换消耗,对性能有一定的影响
- 复杂语句力不从心, 一些复杂的sql语句,用orm对象操作的方式很难实现,就还得用原生sql
1.1 表字段
AutoField # int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField # 一个整数类型,范围在 -2147483648 to 2147483647。
CharField # 字符类型,必须提供max_length参数, max_length表示字符长度。
DateField # 日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField # 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例
EmailField
FileField # 存储文件
FloatField
ImageField # Inherits all attributes and methods from FileField, but also validates that the uploaded object is a valid image.
TextField # 存储文本
UUIDField # 一个用来存储UUID的字段。使用Python的UUID类。
1.2 字段里的参数
null # 用于表示某个字段可以为空。
blank # django的 Admin 中添加数据时是否可允许空值
db_index # 如果db_index=True 则代表着为此字段设置数据库索引。
default # 为该字段设置默认值。
auto_now_add# 创建数据记录的时候会把当前时间添加到数据库 DatetimeField、DateField、TimeField这个三个时间字段可设置
primary_key # If True, this field is the primary key for the model.
unique # 如果设置为unique=True 则该字段在此表中必须是唯一的 。
特殊的:
choices
ForeignKey.on_delete
on_delete就是决定在关联对象被删除时,如何处理当前纪录的,常用的有CASCADE,PROTECT,SET_NULL,SET_DEFAULT
1.3 针对外键
ForeignKey # 外键关联/一对多
ManyToManyField # 多对多
OneToOneField # 一对一
二、连接数据库
1.将默认连接小型文件数据库Sqlite修改为mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'my_db',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
2.在项目的settings.py文件 NSTALLED_APPS中插入app名 当数据库发生改变会进行自动同步
3.使用pymysq连接mysql,在__init__.py中添加
import pymysql
pymysql.install_as_MySQLdb()
4.在apptest下的models.py文件添加类,模型
5. 生成同步文件
python manage.py makemigrations message
django自带一个专门的工具叫migrations, 负责把你的orm表转成实际的表结构,它不旦可以帮自动创建表,对表结构的修改,比如增删改字段、改字段属性等也都能自动同步。
0001_initial.py这个文件就是因为你这条命令而创建的,migrations工具就会根据这个文件来创建数据库里的表
6. 同步到数据
python manage.py migrate
三、用ORM对表数据进行操作
首先进入先进入已经连接好数据库的django python环境
python manage.py shell
然后在shell中导入
from apptest import models
3.1 创建(不用mysql语句)
models.py文件中
from django.db import models
# Create your models here.
class Account(models.Model):
"""账户表"""
username = models.CharField(max_length=64, unique=True) # 用户
email = models.EmailField() # 邮箱
password = models.CharField(max_length=128) # 密码
register_date = models.DateTimeField("注册日期", auto_now_add=True) # 注册日期
signature = models.CharField(verbose_name="签名", max_length=128, blank=True, null=True) # 签名
class Article(models.Model):
"""文章表"""
title = models.CharField(max_length=255, unique=True) # 文章标题
content = models.TextField("文章内容") # 文章内容
account = models.ForeignKey("Account", verbose_name="作者", on_delete=models.CASCADE) # 作者的id
tags = models.ManyToManyField("Tag", blank=True) # 标签
pub_date = models.DateTimeField() # 时间
read_count = models.IntegerField(default=0) # 读过的人数
# ManyToManyField多对多会自动生成中间表 Article_id 与 Tag_id
class Tag(models.Model):
"""文章标签表"""
name = models.CharField(max_length=64, unique=True) # 标签名
date = models.DateTimeField(auto_now_add=True) # 标签创建的时间
创建账户
1. >>> models.Account.objects.create(
... username = "xiaoming",
... email = "xiaoming@qq.com",
... password = "xiaoming123",
... )
2. >>> o = models.Account(
... username = "xiaohong",
... email = "xiaohong@qq.com",
... password = "xiaohong123",
... signature = "i am xiaohong",
... )
>>> o.save()
创建文章
1. >>> o = models.Article(
... title = "dajango初识",
... content = "manage.py urls.py model.py setting.py view.py admin.py views.py",
... pub_date = "2021-11-24"
... )
>>> o.account_id = 1 # 外键关联
>>> o.save()
2. >>> a1=models.Account(
... username="zhangsan",
... email="zhang@san.com",
... password="111",
... )
>>> o = models.Article(
... title='test',
... content='今天很好',
... pub_date='2020-11-11'
... )
>>> o.account=a1 # 外键关联
>>> a1.save() #必需先保存a1
>>> o.save()
创建标签
。。。
关联多对多
赋值:o.tags.set([1,2])
添加:o.tags.add(3,4)
3.2 通过ORM查询数据
filter过滤器:
- contains
- icontains 大小写不敏感
- in
- gt
- gte
- lt
- lte
- startswith
- istartswith
- endswith
- iendswith
- range
- date year month day
- regex
3.3 改删
# 批量修改
models.Account.objects.filter(username='elina').update(password="Luffy#21")
# 单条修改
obj = models.Account.objects.get(username='linux')
obj.username = 'python'
obj.save()
# 批量删除
models.User.objects.get(password='oldboy').delete()
# 单条删除
obj = models.User.objects.get(id=3)
obj.delete()
3.4 ORM对象操作
单表对象操作
o = models.Article.objects.all()[0]
o.tilte
外键关联
>>> o.account.username
'jack'
>>> o.account.username = rain
外键反向关联操作
>>> a = models.Account.objects.get(username='alex')
>>> a.article_set.all()
<QuerySet [<Article: 你好,2018>]>
>>> a.article_set.select_related()
<QuerySet [<Article: 你好,2018>]>
多对多操作
>>> o = models.Article.objects.all()[1]
>>> o.tags.all()
<QuerySet [<Tag: 投资>, <Tag: 科技>]>
多对多反向操作
>>> t = models.Tag.objects.get(name="投资")
>>> t.article_set.all()
<QuerySet [<Article: 你好,2018>, <Article: 粉丝超过10万后,我经历了抖音盗号风波>]>
models中修改显示样式
def __str__(self):
return self.username
def __str__(self):
return "%s -%s" %(self.title,self.account)
def __str__(self):
return self.name