Django模型層(一)單表操做html
1、ORMpython
ORM是「對象-關係-映射」的簡稱。(Object Relational Mapping,簡稱ORM)mysql
orm其實就是將類對象的語法翻譯成sql語句的一個引擎sql
類對象 --- sql數據庫
類 -- 表django
對象 -- 行app
屬性 -- 字段測試
原生sql和Python的orm代碼對比:翻譯
2、Django鏈接數據庫3d
在Django項目的app應用下,有一個 models.py 文件,就是專門用來寫和數據庫相關的代碼的
app01 應用下 的models.py 文件中,寫代碼來建立一個表
from django.db import models
# 建立表 class Userinfo(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=18) age = models.IntegerField() current_date = models.DateField() # 至關於: # create table userinfo( # id int primary key auto_increment, # name vachar(18), # age int, # current_data date # );
不鏈接mysql的話,默認鏈接的是sqlite數據庫,是一個小型文檔數據庫,測試的時候能夠用一下,可是在實際生產中不多用,而是用mysql
使用sqlite的數據庫:
第一次運行時,由於沒有安裝sqlite的驅動,是打不開數據庫的
安裝驅動後再次打開,出現下面狀況就是運行成功了,會顯示咱們製做的表結構
這個時候咱們就能夠添加數據了
鏈接mysql
在配置文件settings中找到:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 修改爲: # 如今終端建立一個庫 orm01 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'POST': 3306, # 端口 默認3306 'NAME': 'orm01', 'USER': 'root', 'PASSWORD': '123', } }
而後在項目文件夾下的 init.py 文件中加入這兩句話:
import pymysql
pymysql.install_as_MySQLdb() # MySQLdb是默認的鏈接數據庫的客戶端模塊,可是不支持Python3.4以上版本,因此要用pymysql把MySQLdb替換掉
最後執行數據庫同步指令
python manage.py makemigrations
python manage.py migrate
進入cmd終端進入mysql查看咱們的表是否插入進去了:
因而可知,咱們插入表的操做算是成功的完成了!!!
3、ORM表單操做
(一)、簡單的增刪改查
類---表 類對象 --- 一行數據 類屬性 --- 字段
先建立一張表,定義四個屬性:
class Student(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=18) age = models.IntegerField() birth_date = models.DateField()
增
建立記錄的 方式一:
def orm(request):
student_obj = models.Student(
name = 'jiege',
age = 23,
birth_date = '1995-01-27'
)
student_obj.save()
return render(request,'myorm.html')
建立記錄的 方式二:
兩種方式
一種 models.Student.objects.create(name='yuhao',...) # 關鍵字
另外一種 models.Student.objects.create(**{'name':'liangdao',....}) # 字典打散
def orm(request):
new_obj = models.Student.objects.create(name='yuhao',age=25,birth_date='1995-02-06')
print(new_obj) # Student object -- model對象
print(new_obj.name) # 點屬性,能夠獲取對應字段的數據
return render(request,'myorm.html')
new_obj = models.Student.objects.create(**{'name':'liangdao','age':'25','birth_date':'1994-07-22'}) print(new_obj) print(new_obj.name) return render(request,'myorm.html')
建立記錄的 方式三:(批量建立,bulk_create)
def orm(request):
obj_list = []
for i in range(5):
obj = models.Student(
name=f'xiaobai{i}',
age=i+1,
birth_date='2000-01-01'
)
obj_list.append(obj)
models.Student.objects.bulk_create(obj_list)
return render(request,'myorm.html')
建立記錄的 方式四:(有就更新,沒有就建立,update_or_create)
def orm(request):
models.Student.objects.update_or_create(
name='baobao',
age=23,
birth_date='1995-03-15'
)
return render(request,'myorm.html')
添加日期的數據,要注意:
方式一:
models.Student.objects.create(birth_date='1996-11-15') # 字符串的形式
方式二:
import datetime
now_date = datetime.datetime.now()
models.Student.objects.create(birth_date=now_date) # 此時插入的仍然是date類型,2019-7-19 這樣
若是想打印orm轉換過程當中的sql,須要在settings中進行以下配置:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
簡單的查
.all方法 查詢全部的數據 返回的是queryset集合
all_objs = models.Student.objects.all()
print(all_objs)
# <QuerySet [<Student: Student object>, <Student: Student object>, <Student: Student object>]> -- 相似於列表 -- queryset集合
all_objs = models.Student.objects.all()
for i in all_objs:
print(i.name)
# jiege、yuhao.....,點屬性能夠取出對應的數據
.filter方法 條件查詢 返回的也是queryset集合,查詢不到內容,不會報錯,返回一個<QuerySet []>空的queryset
objs = models.Student.objects.filter(id=2) # 找id爲2的那條記錄
print(objs) # <QuerySet [<Student: Student object>]>
objs1 = models.Student.objects.filter(name='dazhuang')
print(objs1) # <QuerySet []> 沒找到不報錯,顯示空
objs = models.Student.objects.filter(id=2,name='yuhao')
# 裏面的多個條件用逗號分開,而且這幾個條件必須都成立,是and的關係,or關係搞不定
print(objs) # <QuerySet [<Student: Student object>]>
.get方法 條件查詢 返回的是model對象,並且get方法有且必須只有1個結果
obj = models.Student.objects.get(id=3) # 找id爲3的那條記錄
print(obj) # model對象,Student object
print(obj.name) # 點屬性,能夠取出對應的數據,liangdao
刪
delete方法,queryset 和model對象均可以調用
models.Student.objects.get(id=13).delete() # model對象來調用的delete方法
models.Student.objects.filter(age=1).delete() # queryset調用的delete方法
models.Student.objects.all().delete() # 刪除全部
改
update方法,
只能queryset調用
model對象不能調用更新方法 報錯信息'Student' object has no attribute 'update'
models.Student.objects.get(name='jiege').update(age=28) # .get()返回的是model對象,不能調用update方法,會報錯 models.Student.objects.filter(name='jiege').update(age=28) # .filter()返回的是queryset對象,能夠調用update方法
(二)、查詢接口
all() 查全部
查詢全部結果,結果是queryset類型
filter(**kwargs) 條件查詢
它包含了與所給篩選條件相匹配的對象,結果也是queryset類型
models.Student.objects.filter(id=2,name='yuhao')
# 裏面的多個條件用逗號分開,而且這幾個條件必須都成立,是and的關係,or關係搞不定
models.Student.objects.filter(**{'id':2,'name':'yuhao'}) # 打散形式傳參
get(**kwargs) 條件查詢
返回與所給篩選條件相匹配的對象,不是queryset類型,是行記錄對象,也就是model對象,返回結果有且只有一個,
若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。捕獲異常try。
exclude(**kwargs) 排除
排除的意思,它包含了與所給篩選條件不匹配的對象,沒有不等於的操做昂,用這個exclude,返回值是queryset類型
objects控制器和queryset集合均可以調用exclude,返回結果是queryset類型 # objects控制器調用(objects後直接加exclude方法): query = models.Student.objects.exclude(id=1) print(query) # 找到除了id是1的數據 # queryset集合調用 query = models.Student.objects.filter(age=38).exclude(id=6) print(query) # 找到age是38,除了id是6的數據
order_by(*field) 排序
queryset類型的數據來調用,對查詢結果排序,默認是按照id來升序排列的,返回值仍是queryset類型
objs = models.Student.objects.all().order_by('age') # 默認是按照升序排列的,也就是按照age的升序排列 objs = models.Student.objects.all().order_by('age','id') # 多條件的,逗號隔開,先按照age升序排列,在age相同的狀況下,按id升序排列 objs = models.Student.objects.all().order_by('age','-id') # 降序排列,加一個'-'就能夠
reverse() 反轉
queryset類型的數據來調用,對查詢結果反向排序,返回值仍是queryset類型
# 用在排序以後反轉 query = models.Student.objects.all().order_by('age').reverse() print(query)
count() 計數
queryset類型的數據來調用,返回數據庫中匹配查詢(QuerySet)的對象數量。
objs = models.Student.objects.all().count() print(objs)
first() 第一條記錄
queryset類型的數據來調用,返回第一條記錄,獲得的都是model對象,不是queryset
obj = models.Student.objects.all().first() print(obj)
last() 最後一條記錄
queryset類型的數據來調用,返回最後一條記錄,結果爲model對象類型
obj1 = models.Student.objects.all().last() print(obj1)
exists() 判斷是否包含查的數據,返回True或False
queryset類型的數據來調用,若是QuerySet包含數據,就返回True,不然返回False
空的queryset類型數據也有布爾值True和False,可是通常不用它來判斷數據庫裏面是否是有數據,若是有大量的數據,你用它來判斷,那麼就須要查詢出全部的數據,效率太差了,用count或者exits 例:all_books = models.Book.objects.all().exists() # 翻譯成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,就是經過limit 1,取一條來看看是否是有數據
values(*field) 用的比較多 返回一個字典序列
queryset類型的數據來調用,返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列,只要是返回的queryset類型,就能夠繼續鏈式調用queryset類型的其餘的查找方法,其餘方法也是同樣的。
obj = models.Student.objects.filter(age=25).values() print(obj) # <QuerySet [{'id': 2, 'name': 'yuhao', 'age': 25, 'birth_date': datetime.date(1995, 2, 6)}, {'id': 3, 'name': 'liangdao', 'age': 25, 'birth_date': datetime.date(1994, 7, 22)}]> obj = models.Student.objects.filter(age=25).values('name','age') print(obj) # <QuerySet [{'id': 2, 'name': 'yuhao', 'age': 25}, {'id': 3, 'name': 'liangdao', 'age': 25 }]>
values_list(*field) 返回一個元組序列
它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列
obj = models.Student.objects.filter(age=25).values_list('name','age') print(obj) # <QuerySet [('yuhao', 25), ('liangdao', 25)]>
distinct() 去重
values和values_list獲得的queryset類型的數據來調用,從返回結果中剔除重複紀錄,結果仍是queryset
query = models.Student.objects.all().values('age').distinct() print(query)
(三)、基於雙下劃線的模糊查詢
1. __in=[] 值等於列表裏任意一個的對象 obj = models.Student.objects.filter(age__in=[22,25,28]) print(obj) # <QuerySet [<Student: jiege>, <Student: yuhao>, <Student: liangdao>, <Student: zhumo>]> 2. __gt 大於 __gte 大於等於 obj = models.Student.objects.filter(age__gt=25) print(obj) # <QuerySet [<Student: jiege>]> # 注意,別寫age>25,這種參數不支持 3. __lt 小於 __lte 小於等於 4. __range=[] 值在一個範圍內 obj = models.Student.objects.filter(age__range=[22,25]) print(obj) # sql的between and,大於等於22,小於等於25 5. __contains 包含 obj = models.Student.objects.filter(name__contains='xiao') print(obj) # name中包含xiao的 6. __icontains 包含,不區分大小寫 obj = models.Student.objects.filter(name__contains='xiao') print(obj) # name中包含xiao的,不區分大小寫,好比Xiao這種也能識別出來 7. __startswith 以什麼開頭 __endswith 以什麼結尾 8. __year 找日期年份相關的 __month 月份 obj = models.Student.objects.filter(birth_date__year='1995') print(obj) # 找生日是1995年的人 obj1 = models.Student.objects.filter(birth_date__year='1995',birth_date__month='01') print(obj1) # 找生日是1995年1月份的人
.