1. ORM 介绍
1. ORM 概念
对象关系映射 (Object Relational Mapping, 简称 ORM) 模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.
简单的说, ORM 是通过使用描述对象和数据库之间映射的元数据, 将程序中的对象自动持久化到关系数据库中.
ORM 在业务逻辑层和数据库层之间充当了桥梁的作用.
2. 优势
ORM 解决的主要问题是对象和关系的映射. 它通常将一个类和一张表一一对应, 类的每个实例对应表中的一条记录, 类的每个属性对应表中的每个字段.
ORM 提供了对数据库的映射, 不用直接编写 SQL 代码, 只需操作对象就能对数据库操作数据.
让软件开发人员专注于业务逻辑的处理, 提高了开发效率.
3. 缺点
ORM 的缺点是会在一定程度上牺牲程序的执行效率.
ORM 的操作是有限的, 也就是 ORM 定义好的操作是可以完成的, 一些复杂的查询操作是完成不了.
ORM 用多了 SQL 语句就不会写了, 关系数据库相关技能退化...
2. django 中的 ORM
1. 常用字段
AutoField 自增 primary_key=True 主键
- CharField # 字符串 字符类型, 必须提供 max_length 参数. max_length 表示字符的长度.
- TextField # 大字符串 文本类型
- IntegerField # 整形 一个整数类型. 数值的范围是 -2147483648 ~ 2147483647.
- DateTimeField DateField # 日期 日期时间
auto_now: 每次修改时修改为当前日期时间.
auto_now_add: 新创建对象时自动添加当前日期时间.
auto_now 和 auto_now_add 和 default 参数是互斥的, 不能同时设置.
- BooleanField # 布尔值
- DecimalField max_digits=5 decimal_places=2 #一共 5 位, 小数点 2 位, 最大值为: 999.99
2. 字段参数
null=True 数据库中该字段可以为空
blank=True 用户输入可以为空
default 默认值
db_index=True 索引
unique 唯一约束
verbose_name 显示的名称
choices 可选择的参数
3. 批量插入(bulk_create)
- # bulk_create # [b?lk]
- obj_list = []
- for i in range(20):
- #创建实例化对象, 批量创建
- obj = models.Book(
- title=f'金梅{i}',
- price=20+i,
- publish_date=f'2019-09-{i+1}',
- publish='24 期出版社'
- )
- obj_list.append(obj)
- models.Book.objects.bulk_create(obj_list) #批量创建
** 打散拆解字典
request.POST -- querydict 类型 {'title': ['asdf'], 'price': ['212'], 'publish_date': ['2019-09-12'], 'publish': ['asdf']}
data = request.POST.dict() -- 能够将 querydict 转换为普通的 python 字典格式
创建数据
- models.Book.objects.create(
- # title=title,
- # price=price,
- # publish_date=publish_date,
- # publish=publish
- **data #同上内容
- )
4. admin 建表操作
注册
- python manage.py createsuperuser
- Username : weihe Password: weihe666
admin.py 中表信息
- from django.contrib import admin
- from app01 import models
- admin.site.register(models.Book)
- admin.site.register(models.Author)
- admin.site.register(models.Publish)
- admin.site.register(models.AuthorDetail)
5. ORM 操作数据库
一般在 models 文件添加__str__方法
__str__ returned non-string (type int) 必须返回字符串
- def __str__(self):
- return self.title
1. models 表结构
- from django.db import models
- # Create your models here.
- class Author(models.Model):
- """
- 作者表
- """
- name=models.CharField( max_length=32)
- age=models.IntegerField()
- # authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE) #
- au=models.OneToOneField("AuthorDetail",on_delete=models.CASCADE)
- class AuthorDetail(models.Model):
- """
- 作者详细信息表
- """
- birthday=models.DateField()
- telephone=models.CharField(max_length=11)
- addr=models.CharField(max_length=64)
- # class Meta:
- # db_table='authordetail' #指定表名
- # ordering = ['-id',]
- class Publish(models.Model):
- """
- 出版社表
- """
- name=models.CharField( max_length=32)
- city=models.CharField( max_length=32)
- class Book(models.Model):
- """
- 书籍表
- """
- title = models.CharField( max_length=32)
- publishDate=models.DateField()
- price=models.DecimalField(max_digits=5,decimal_places=2)
- publishs=models.ForeignKey(to="Publish",on_delete=models.CASCADE,)
- authors=models.ManyToManyField('Author',)
2. API 13 种方法
1.all()方法
models. 类名. objects.all() 查询所有结果, 结果是 QuerySet 类型, 里边的值都是对象, 可以通过 for 循环取出对象, 然后点属性得到值(面向对象)
2.filter()筛选
- ret = models.Book.objects.filter()
- print(ret)
得到的是 QuerySet 对象, 没有参数时得到所有对象,
- ret = models.Book.objects.filter(id=14,title="python")
- print(ret)
得到的是 QuerySet 对象, 有参数且能找到返回当前 title 对象
- ret = models.Book.objects.filter(id=100)
- print(ret)
得到的是 QuerySet 对象, 有参数但是查不到内容, 返回空的 < QuerySet []>
- ret = models.Book.objects.filter(pdate="2012-12-12").filter(publisher="北京出版社")
- print(ret)
得到的是 QuerySet 对象, 可以再次使用 filter()方法
- 3. get()
- ret = models.Book.objects.get()
1. 超过一个就报错 :returned more than one Book -- it returned 13!
- ret = models.Book.objects.get(id=100)
- print(ret)
2. 查不到数据会报错 :Book matching query does not exist.
- ret = models.Book.objects.get(id=10)
- print(ret)
3. 可以匹配到数据, 返回 models 对象, 由于 str 方法得到 title 的值
- 4. exclude() #排除
- ret = models.Book.objects.exclude(title__startswith="python")
- print(ret)
1.objects 类型调用, 匹配到所有不是以 python 开头的 QuerySet 对象
- ret = models.Book.objects.all().exclude(title__startswith="python")
- print(ret)
2.QuerySet 类型数据能够调用, 匹配到所有不是以 python 开头的 QuerySet 对象
5. order_by()排序
- ret = models.Book.objects.all().order_by("-price")
- print(ret)
queryset 类型的数据来调用, 对查询结果排序, 默认是按照 price 倒序, 返回值还是 queryset 类型
6. reverse() 反转
- ret = models.Book.objects.all().order_by("id").reverse()
- print(ret)
- # 数据排序之后才能反转
7. count() 计数
fitst() 第一个数据
last() 最后一个数据
ret = models.Book.objects.all().count()
print(ret) ---- 统计返回结果的数量
first() 返回第一条数据, 结果是 model 对象类型
last() 返回最后一条数据, 结果是 model 对象类型
- # ret = models.Book.objects.all().first() = models.Books.objects.all()[0]
- ret = models.Book.objects.all().last()
8. exists() 是否存在
- ret = models.Book.objects.filter(id=100).exists()
- print(ret)
queryset 类型的数据来调用, 如果 QuerySet 包含数据, 就返回 True, 否则返回 False
- 9. values()
- values(返回的 queryset, 里面是字典类型数据)
- values_list(返回的 queryset, 里面是元组类型数据)
- ret = models.Book.objects.filter(id=12).values("title","price")
- print(ret)
得到 QuerySet 类型 id=12 的只含有 "title","price" 属性的字典对象
- # ret = models.Book.objects.all().values_list('title','price')
- # ret = models.Book.objects.all().values()
- # ret = models.Book.objects.values() #调用 values 或者 values_list 的是 objects 控制器, 那么返回所有数据
10.distinct() 去重
配合 values 和 values_list 来使用
- ret = models.Book.objects.all().values('publisher').distinct()
- print(ret)
3. filter 双下方法
- # ret = models.Book.objects.filter(price__gt=35) #大于
- # ret = models.Book.objects.filter(price__gte=35) # 大于等于
- # ret = models.Book.objects.filter(price__lt=35) # 小于
- # ret = models.Book.objects.filter(price__lte=35) # 小于等于
- # ret = models.Book.objects.filter(price__in=[35,44,66,88]) # 在其中
- # ret = models.Book.objects.filter(price__range=[35,38]) # 大于等 35, 小于等于 38 # where price between 35 and 38
- # ret = models.Book.objects.filter(title__contains='金梅') # 字段数据中包含这个字符串的数据都要
- # ret = models.Book.objects.filter(title__contains='金梅')
- # ret = models.Book.objects.filter(title__icontains="python") # 不区分大小写
- # from app01.models import Book
- # ret = models.Book.objects.filter(title__icontains="python") # 不区分大小写
- # ret = models.Book.objects.filter(title__startswith="py") # 以什么开头, istartswith 不区分大小写
- # ret = models.Book.objects.filter(publish_date='2019-09-15')
某年某月某日:
- ret = models.Book.objects.filter(pdate__year='2018')
- ret = models.Book.objects.filter(pdate__month='08')
- ret = models.Book.objects.filter(pdate__year__gt='2018')
- ret = models.Book.objects.filter(pdate__day='1')
找字段数据为空的双下滑线
- models.Book.objects.filter(publish_date__isnull=True) #这个字段值为空的那些数据
- 1. ORM
定义: object relations mapping, 对象关系映射. 它实现了数据模型与数据库的解耦
每个数据库有自己的 sql 语句, 不通用.
1. 将对象翻译成 sql 语句
2.Django 内置的一个 pymysql 客户端将 sql 语句发送给 MySQL 服务端
3. 服务端拿到 sql, 到磁盘里面进行数据操作
Django 默认数据库为 sqlite3, 比较鸡肋, 设置为 MySQL 数据库修改 settings 配置文件
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql', #Django 中数据库地址
- 'NAME':'bms', # 要连接的数据库名, 连接前先 cmd 建库
- 'USER':'root', # 连接数据库的用户名
- 'PASSWORD':'', # 连接数据库的密码
- 'HOST':'127.0.0.1', # 连接主机, 默认本级
- 'PORT':3306, # 端口 默认 3306
- }
- }
如有必要, 可以为自己的项目下的 App 配置单独的数据库, 如下代码
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME':'bms', # 要连接的数据库, 连接前需要创建好
- 'USER':'root', # 连接数据库的用户名
- 'PASSWORD':'', # 连接数据库的密码
- 'HOST':'127.0.0.1', # 连接主机, 默认本级
- 'PORT':3306 # 端口 默认 3306
- },
- 'app01': { #可以为每个 App 都配置自己的数据, 并且数据库还可以指定别的, 也就是不一定就是 MySQL, 也可以指定 SQLite 等其他的数据库
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME':'bms', # 要连接的数据库, 连接前需要创建好
- 'USER':'root', # 连接数据库的用户名
- 'PASSWORD':'', # 连接数据库的密码
- 'HOST':'127.0.0.1', # 连接主机, 默认本级
- 'PORT':3306 # 端口 默认 3306
- }
- }
来源: http://www.bubuko.com/infodetail-3269675.html