Django--ORM和單表查詢
阿新 • • 發佈:2019-04-08
指定 寫上 nal 大於 支持 由於 有一個 應用 數據庫遷移
一 . ORM
ORM是“對象-關系-映射”的簡稱。(Object Relational Mapping,簡稱ORM)
二. 單表操作
要想將模型轉為mysql數據庫中的表,需要在setting裏面寫上這個,把原來帶的替換掉
DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘: ‘book‘, # 要連接的數據庫名,連接前需要創建好 ‘USER‘: ‘root‘, # 連接數據庫的用戶名 ‘PASSWORD‘: ‘666‘, # 連接數據庫的密碼 ‘HOST‘: ‘127.0.0.1‘, # 連接主機,默認本機 ‘PORT‘: 3306 # 端口 默認3306 } }
還需在項目名下的__init__的文件中寫 : 寫成這個的目的是將django默認的驅動MySQLdb 改為 pyMySQL,因為MySQLdb對於py3有很大的問題.
import pymysql pymysql.install_as_MySQLdb()
通過兩條數據庫遷移命令在指定數據庫建表
python manage.py makemigrations #生成記錄,每次修改了models裏面的內容或者添加了新的app,新的app裏面寫了models裏面的內容,都要執行這兩條 python manage.py migrate #執行上面這個語句的記錄來創建表,生成的表名字前面會自帶應用的名字,例如:你的book表在mysql裏面叫做 app01_book 表
然後需要在python裏面查看呢表中內容,需要進行下列操作
如果想打印ORM轉換過程中的SQL語句,需要在setting中設置配置:
LOGGING = { ‘version‘: 1, ‘disable_existing_loggers‘: False, ‘handlers‘: { ‘console‘:{ ‘level‘:‘DEBUG‘, ‘class‘:‘logging.StreamHandler‘, }, }, ‘loggers‘: { ‘django.db.backends‘: { ‘handlers‘: [‘console‘], ‘propagate‘: True, ‘level‘:‘DEBUG‘, }, } }
三 . 增刪改查相關操作
在python中ORM三種對應關系
類----------------->表
類對象----------->行(記錄) # 可以進行增刪改查操作 (.create, .delete(), .update(), .filter(id=1), )
類屬性----------->表字段
# 增加 # 方法一 book_obj = models.Book(name=‘吳彥祖‘, gender=‘男‘) # 如果是日期個格式必須寫2018-01-01 這種格式 book_obj.save() # 方法二 models.Book.objects.create(name=‘吳彥祖‘,gender=‘男‘) # 這裏的Book是models.py文件裏面的類名 # 批量增加 obj_list = [] for i in range(100): obj = models.UserMsg( username= ‘daniel%s‘ %i, password=‘abc%s‘ %i ) obj_list.append(obj) models.UserMsg.objects.bulk_create(obj_list)
# 查詢 obj = models.Book.objects.filter(id=1) # 查詢id=1的對象 即使是篩選出來的只有一個,那麽也要在後面加上[索引],因為裝在列表裏. obj = models.Book.objects.all() # 查詢所有的數據 # 上面的obj都是一個類似於用列表裝的對象,要想取出來,可以使用for循環,或者後面加上[索引], # 然後想要取到對應的字段,直接點字段就可以, 例如obj[0].name 就是取到該行的name字段的數據.
# 刪除 models.Book.objects.all().delete() # 刪除所有數據 models.Book.objects.filter(id=1).delete() # 刪除id=1的數據
# 改 models.Book.objects.filter(id=1).update(name=‘劉德華‘) # 把id=1的姓名改為劉德華
四 . mdels.py的__str__方法
from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2,) pub_date = models.DateTimeField() #必須存這種格式"2012-12-12" publish = models.CharField(max_length=32) def __str__(self): #後添加這個str方法,也不需要重新執行同步數據庫的指令 return self.name #當我們打印這個類的對象的時候,顯示name值 # 這時候你要打印query set對象的時候就會顯示name名字,看著明白些
五 . 查詢表記錄(重點)
Book.objects調用下面這些方法:
# 調用這些方法必須是queryset類型的,也就是說調用完下列方法後結果還是queryset類型的可以繼續調用下列的方法 Q <1> all() : # 結果是queryset類型 Q <2> filter(**kwargs): 裏面的關鍵字參數用逗號隔開,表示and的意思# 結果是queryset類型 <3> get(**kwargs): 結果是model對象,相當於queryset對象[索引]之後的,返回的結果有且只有一個 Q <4> exclude(**kwargs): 排除的意思,除了括號裏面的都要, # 結果是queryset類型 Q <5> order_by(*字段): 排序,默認升序,前面加負號(-)就是降序,括號裏面要加引號 # 寫兩個參數就是第一個參數相同的情況下,按照第二個參數排序. # 結果是queryset類型 Q <6>reverse(): 對查詢結果反向排序,可以在order_by後面直接寫 # 結果是queryset對象 Q <7>count(): 匹配查詢(queryset)對象, # 結果是queryset類型 <8>first(): 返回第一條記錄 是model對象 <9>last(): 返回最後一條記錄 是model對象 <10>exists(): 如果有數據就返回True,沒有就返回False Q <11>values(*字段): 用的比較多,返回可叠代字典的序列 # 是一個特殊的queryset類型 Q <12>values_list(*字段): 和values很像,返回的是一個元組序列 # 是一個特殊的queryset類型 Q <13> distinct(): 一定要寫在values或者values_list後面進行去重, 例: values(‘name‘).distinct()
# 序號前面有Q的都是Queryset類型
values(*字段)的用法
all_books = models.Book.objects.all().values(‘name‘,‘id‘) print(all_books) #<QuerySet [{‘name‘: ‘九陽神功‘, ‘id‘: 1}, {‘name‘: ‘吸星大法‘, ‘id‘: 2}]>
values_list(*字段)的用法
all_books = models.Book.objects.all().values_list(‘id‘,‘name‘) print(all_books) #<QuerySet [(1, ‘九陽神功‘), (2, ‘吸星大法‘)]> # 裏面是元組
distinct()的用法
# all_books = models.Book.objects.all().distinct() #這樣寫是表示記錄中所有的字段重復才叫重復. # all_books = models.Book.objects.all().distinct(‘price‘) #報錯,不能在distinct裏面加字段名稱 # all_books = models.Book.objects.all().values(‘price‘).distinct() 如果values 中有兩個參數,那麽需要這兩個都重復才去掉
# 打印結果<QuerySet [(Decimal(‘33.00‘),), (Decimal(‘111.00‘),)]>
基於雙下劃線的模糊查詢
Book.objects.filter(price__in=[100,200,300]) #price值等於這三個裏面的任意一個的對象 Book.objects.filter(price__gt=100) #大於,大於等於是price__gte=100,不支持price>100這種參數 Book.objects.filter(price__lt=100) # 小於 Book.objects.filter(price__range=[100,200]) #sql的between and,大於等於100,小於等於200 Book.objects.filter(title__contains="python") #title值中包含python的 Book.objects.filter(title__icontains="python") #不區分大小寫 Book.objects.filter(title__startswith="py") #以什麽開頭,istartswith 不區分大小寫 Book.objects.filter(pub_date__year=2012) # 查找2012年的數據
# 得到的都是queryset類型 # __month 查找月 __day 查找日 # 如果明明有要找的日期,但是報錯,在setting的配置文件中把 USE_TZ 改為 False,這是由於mysql數據庫和django的數據庫時區不同導致的
Django--ORM和單表查詢