ORM(Object Relational Mapping)對象關係映射
目錄
ORM(Object Relational Mapping)對象關係映射
1、特點:
- 提高了開發效率,ORM可以自動的對實體對象和數據庫中的Table進行字段與屬性的映射,可以省略龐大的數據訪問層
- 不用SQL編碼,能夠直接對數據庫進行CRUD操作(CREATE、RETRIEVE、UPDATE、DELETE)
2、支持的數據庫:
sqlite、mysql、oracle....
3、Model模型:
數據字段
字段 | 描述 |
---|---|
AutoField | 自動增長,通常不需要指定,django自動創建名爲id的自動增長屬性 |
CharField | 字符串,必須指定的參數: max_length 最大字符 |
TesxtFiled | 大文本字段,一般超過4000個字符 |
IntegerField | 整形 |
BooleanField | 布爾,支持True、False |
NullBooleanField | 布爾,支持Null、True、False |
DateFiled: [auto_now=False, auto_now_add=False] |
|
DateTimeField | 日期時間 |
DecimalFiled(max_digits=None, decimal_places=None): |
|
FloatField | 浮點數,有誤差 |
FileField | 上傳文件字段 ImageField 繼承於FileFiled,對上傳的內容進行校驗,確保是有效地圖片 |
ForeignKey | 外鍵,建立一對多關係 |
字段選項
字段選項 | 描述 |
---|---|
null | 判斷是否爲空 |
blank | 後臺填寫的數據是否可以爲空白 |
choice | 作爲數據選項 |
default | 設置默認值 |
primary_key | 標識主鍵 |
verbose_name | 爲字段起別名 |
db_column | 指定列名 |
db_index | 指定列的順序 |
關係字段類型
關係類型 | 描述 |
---|---|
ForeignKey | 一對多,將字段定義在多的一端中 |
ManyToManyField | 多對多,將字段定義在任意一端中 |
OneToOneField | 一對一,將字段定義在任意一端中 |
元類Meta
作用:修改數據庫表的默認名稱
# 書籍信息模型
class BookInfo(models.Model):
name = models.CharField(max_length=20) #圖書名稱
class Meta: #元信息類
db_table = 'bookinfo' #自定義表的名字
模型管理器
所有的查詢操作要在Entry.objects基礎上完成的
在Django創建對象時,都會默認創建一個object屬性,是一個manage類,有一下幾種方法
objects管理器中的方法 | 返回類型 | 作用 |
---|---|---|
Entry.objects.get() | 模型對象 | 返回一個對象,有且只能有一個: 查到多條數據,報錯:MultipleObjectsReturned 查詢不到數據,報錯:DoesNotExist |
Entry.objects.all() | QuerySet | 返回所有的對象 |
Entry.objects.all().values('name') | 返回所有行某一列的值 | |
Entry.objects.filter() | QuerySet | 返回滿足條件的對象 |
Entry.objects.exclude() | QuerySet | 取反,返回不滿足條件的對象 |
Entry.objects.order_by() | QuerySet |
按指定的字段們進行排序,如果是多個的話中間用 , 隔開 默認升序 名稱前加 - 爲降序 |
Entry.objects.aggregate() | 字典,例如: {‘salary__avg’: 9500.0} |
進行聚合操作 Sum, Count, Max, Min, Avg |
Entry.objects.count() | 數字 | 返回查詢集中對象的數目 |
增刪改查操作
# 增
- 創建一個實體對象 obj = Entry(屬性=值,屬性=值)
- 保存 obj.save()
# 單個刪
- 獲取刪除的對象obj = Author.object.get(id=1)
- 調用delete() obj.delete()
# 批量刪
- Author.object.all().delete()
# 單個修改
- 先通過get獲取到響應的Model對象 obj = Author.objects.get(id=1)
- Model對象修改值 obj.name = 'lily'
# 批量修改
- 調用update() Author.objects.all().update(字段=‘值’)
# F對象:用於比較表中兩個字段
# 查詢age 大於四倍 id
from django.db.models import F
Employee.objects.filter(age__gt=F('id') * 4)
# Q對象:對查詢條件進行與或非(&|~)的邏輯操作,多個條件
# 查詢年齡大於30 且 id 大於3
from django.db.models import Q
select * from test01_employee where id > 3 and age > 30;
Employee.objects.filter(id__gt=3, age__gt=30)
Employee.objects.filter(Q(id__gte=3)&Q(age__gte=30))
# 查詢id不等於3
Employee.objects.filter(~Q(id=3)) -> 波浪線
# 條件查詢
- 判等:exact
# 例:查詢id爲1的員工 # select * from test01_employee where id = 1; Employee.objects.filter(id__exact=1) Employee.objects.filter(id=1)
- 不等:exclude
# 查詢id 不等於 1 # select * from test01_employee where id != 1; Employee.objects.exclude(id=1)
- 模糊查詢:contains,endswith/startswith
# 查詢包含馬的員工 # select * from test01_employee where name = “%馬%"; Employee.objects.filter(name__contains='馬')
- 空查詢:isnull
# 查詢comment 不爲空 # select * from test01_employee where comment is not null; Employee.objects.filter(comment__isnull=False)
- 範圍查詢:in/not in/between...and
# select * from test01_employee where id in (1, 3, 5); Employee.objects.filter(id__in=(1, 3, 5)) # where id between 4 and 8 [4,8] UserInfo.objects.filter(id__range=[4,8])
- 比較查詢:gte(>=),lte(<=),gt(>),lt(<)
# 查詢年齡大於等於30 Employee.objects.filter(age__gte=30)
- 日期查詢:year、month、day、week_day、hour、minute、second
# select * from test01_employee where year(hire_date) = 2015; Employee.objects.filter(hire_date__year=2015)
# 關聯查詢
- 通過對象
# 一對多 departement.employee_set.all() # 多對一 employee.department
# order_by方法
# 統計id 大於等於3,降序排列
# select * from test01_employee where id > 3 order by age desc; -> [asc升序]
Employee.objects.filter(id__gt=3).order_by('-age')
# aggregate方法
常用聚合類Sum, Count, Max, Min, Avg,返回字典{‘屬性名__聚合函數’: 值}
from django.db.models import Count, Avg
# 查詢總人數
# select count(*) from test01_employee;
Employee.objects.aggregate(Count('id’))
>>> {'id__count': 10}
# 查詢工資平均數
# select avg(salary) from test01_employee;
Employee.objects.aggregate(Avg('salary’))
>>> {'salary__avg': 9600.0}
# count()方法
# 查詢id大於等於3的人數
# select count(*) from test01_employee where id >= 3;
Employee.objects.filter(id__gte=3).count()
# QuerySet查詢集
- 爲一個數列,下標不能夠爲負,可以進行切片操作,datas[0:1:-1]
- 擁有get(),同objects管理器相同
- 擁有exists(),判斷數列中是否有數據
- 惰性查詢:創建QuerySet的時候不會馬上查詢數據庫,當訪問數據的時候纔會發起查詢操作
datas = Department.objects.all() # 不會查詢
- 緩存:當首次查詢時,會緩存,再次查詢時會使用之前查詢的數據, 但是使用索引或者切片操作,就不會緩存
datas = Department.objects.all() # 首次遍歷,緩存數據 [deps.name for deps in datas] # 不會查詢數據庫 [deps.name for deps in datas] datas = Department.objects.all() # 會查詢數據庫 datas[0] # 會查詢數據庫 datas[0]
# 自關聯:查詢父級和子級目錄
class Area(models.Model):
title = models.CharField(max_length=20)
parent = models.ForeignKey(‘self’, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.title
+------+-----------------------------------------------+-----------+
| id | title | parent_id |
+------+-----------------------------------------------+-----------+
| 1 | 中國 | NULL |
| 2 | 北京市 | 1 |
| 3 | 天津市 | 1 |
+------+-----------------------------------------------+-----------+
from app01.models import *
a = Area.objects.get(id=232)
# 獲得父級
a.parent.title >>> ‘廣東省’
# 獲得子級
a.area_set.all() >>> ….