Django學習筆記(3)orm模型操作
orm概述
什麼是ORM
1.Python、PHP、Java是一種開發語言,而MySQL、SQL Server則採用資料庫語言,不同語言之間如何實現互操作?
2.SQL語言包括包括資料定義語言DDL、資料控制語言DCL、資料查詢語言DQL、資料操作語言DML等,例如INSERT、DELETE、SELECT、UPDATE操作。
3.作為開發人員,應該把精力放在核心業務程式碼的編寫上面,而不應該花太多精力跟資料庫語言打交道。
4.ORM(Object-Relational Mapping,物件關係對映)技術可以看做是開發者和資料庫之間的橋樑,用於實現資料庫和程式語言之間的對映,本質上來看,ORM就是將SQL操作和程式語言操作做了一個翻譯。
5.通過ORM技術來操作資料庫,使得開發者無需接觸SQL語句,而直接操作物件的屬性和方法,大大提高了開發效率。
orm的功能
1.對映技術:資料型別對映、類對映、關係對映。例如,每一張資料庫表對應開發語言的類,每一個數據欄位對應類中的屬性。
2.CRUD操作:CRUD即增刪查改操作,在SQL語句中通過Insert、Select、Update、Delete來實現,在ORM庫中則需要
3.通過對應的函式來實現,例如Django ORM通過get、filter、save、delete函式進行操作。
4.快取優化:(惰性操作)從資料庫查詢到的資料以類物件的形式儲存在記憶體,用於隨時提取;真正需要查詢結果時才執行資料庫的select操作,而不是在ORM查詢命令執行時查詢資料庫。
Models介紹
1.通常情況,一個Models對應資料庫的一張表
2.Django中Models以類的形式表現
3.它包含了一些基本欄位以及資料的一些行為
4.我們只需要在類裡面進行操作,就可以操作資料庫,表,不需要直接使用SQL語句
5.我們通過建立類來建立資料表,所以對資料庫的操作,都是對類與對類的物件進行操作,而不使用sql語句
6.ORM物件關係對映,實現了物件和資料庫的對映,隱藏了資料訪問的細節,不需要編寫SQL語句
models的屬性與欄位(field)
常用欄位型別
AutoField():一個IntegerField,根據可用ID自動遞增。如果沒指定主鍵,就建立它自動設定為主鍵。
IntegerField():一個整數;
FloatField:浮點型
CharField(max_length = None):字串欄位False
DateField(auto_now=False, auto_now_add=False):日期;引數auto_now:每次儲存物件時,自動設定該欄位為當前時間。用於"最後一次修改"的時間戳.注意,它總是使用當前日期,預設為False。引數auto_now_add:當物件第一次被建立時自動設定當前時間。用於建立時間的時間戳.它總是使用當前日期,預設為False;引數auto_nowauto_now_add default是互相排斥的,組合會發生錯誤
TImeFiled():時間,引數同DateField
TextField():一個很長的的文字欄位,不超過4000字元
BooleanField():布林欄位,True或False;
NullBooleanField():值為Null,True,False;
DecimalField():十進位制浮點數,引數max_digits表示總數,引數decimal_places表示小數點數
FileField():上傳檔案欄位
ImageField():用於上傳圖片並驗證圖片合法性,需定義upload_to引數,使用本欄位需安裝pip install pillow圖片庫;設定upload_to 到某個目錄下,需要在settings.py中配置多媒體檔案路徑: MEDIA_ROOT = os.path.join(BASE_DIR,'static'); models.ImageField(upload_to="article_img" )表示會將從static目錄下的article_img資料夾上傳圖片
OneToOneField(to, on_delete, parent_link = False):一對一
ForeignKey(to, on_delete):一對多
ManyToManyField(to):多對多
欄位引數
null:如果設定為True,當該欄位為空時,Django會將資料庫中該欄位設定為NULL。預設為False 。
blank:如果設定為True,該欄位允許為空。預設為False。
default:該欄位的預設值。可以是一個值或者是個可呼叫的物件,如果是個可呼叫物件,每次例項化模型時都會呼叫該物件。
primary_key:如果設定為 True ,將該欄位設定為該模型的主鍵。
unique:如果設定為 True,這個欄位的值必須在整個表中保持唯一。
verbose_name:任何欄位型別都接收一個可選的位置引數,如果未指定Django會自動使用欄位的屬性名作為該引數值,並且把下劃線轉換為空格。
max_length
:設定預設長度,一般在CharField、TextField、EmailField等文字欄位設定
choices
:設定該欄位的可選值,本欄位的值是一個二維元素的元祖;元素的第1個值為實際儲存的值,第2個值為HTML頁面顯示的值
upload_to
:設定上傳路徑,ImageField和FileField欄位需要設定此引數,如果路徑不存在,會自動建立
Meta類屬性
verbose_name:設定物件名稱(例如usecms),若沒有設定,則預設為該類名的小寫分詞形式,例如類名為CamelCase會被轉換為camel case;
verbose_name_plural:設定物件名稱複數(例如usercms),一般設定跟verbose_name一樣,verbose_name_plural=verbose_name否則會預設加s;
db_table:設定對映的資料表名,預設為“應用名_模型名”,即用該模型所在app的名稱加本模型類的名稱
ordering :排序規則,按照哪個欄位排unique_together序,加上負號是降序 ,ordering = ['id','-create_time']
unique_together :聯合主鍵 unique_together = ('name','id_card')
proxy:設定True or False,設定本模型及所有繼承本模型的子模型是否為代理模型;
abstract:設定True or False,設定本模型類是否為抽象基類;如果是抽象基類,那麼是不會建立這張表的,這張表用來作為基類被其他的表繼承
同步到資料庫
1 python manage.py makemigrations #生成遷移檔案 2 python manage.py migrate #同步到資料庫中
QuerySet增刪改查
1 #from user.models import Category#操作哪個table就import哪個類 2 3 # 運算子(不等於/大於/小於/包含) 4 # Category.objects.filter(name__endswith='xx')#以xx結尾 5 # Category.objects.filter(name__startswith='xx')#以xx開頭 6 # Category.objects.exclude(name="首頁")#exclude-不等於,排除name="首頁"的資料 7 #多級運算,通過多層點 8 # Category.objects.exclude(name="首頁").filter(id__gte=3)#先找name !="首頁",再找id>=3 9 # Category.objects.filter(name__startswith='李').exclude(sex='女') 10 # print(Category.objects.filter(name__contains='l'))#包含'l' 11 # Category.objects.filter(name__icontains='l')#包含'l'或者'L',加了'i'就不區分大小寫 12 # print(Category.objects.filter(name__in=['首頁','Mysql','python'])) #in 13 14 15 # #建立 16 # obj = models.Article.objects.create(title='title_model',desc='desc1',content='content') 17 # obj.title = 'new_title' 18 # obj.save() 19 # 20 # obj2 = models.Article(title='title_model',desc='desc1',content='content') 21 # obj2.save() 22 23 24 # #查詢 25 # models.Article.objects.get(id=1)#單個查詢,條件只能是唯一的,否則會報錯 26 # models.Article.objects.filter(title='xiaohei',desc='desc1')#多條件查詢,返回多條資料,寫多個引數就是and 27 # models.Article.objects.all().filter(title='xiaohei').values()#字典顯示 28 # models.Article.objects.all().count()#個數 29 # models.Article.objects.raw('select * from user_article;') # 執行原生sql 30 # models.Article.objects.filter(title__contains='模糊查詢') 31 # models.Article.objects.filter(title__endswith='開頭') 32 # models.Article.objects.filter(title__startswith='結尾') 33 # models.Article.objects.filter(title__in=['title1','title2']) 34 # models.Article.objects.filter(title__isnull=True)#為空 35 # models.Article.objects.exclude(title__in=['title1','title2'])#排除 36 # models.Article.objects.filter(read_count__gt=1) 37 # models.Article.objects.filter(read_count__gte=1) 38 # models.Article.objects.filter(read_count__lt=1) 39 # models.Article.objects.filter(read_count__lte=1) 40 # models.Article.objects.filter(read_count__range=(1,2,3)) 41 42 #排序 43 #Category.objects.all().order_by("is_delete") #通過is_delete欄位排序,可通過多欄位排序 44 45 #修改 46 # art = models.Article.objects.get(pk=1) 47 # art.title = 't1223' 48 # art.save() 49 # 50 # models.Article.objects.filter(title__isnull=True).update(title='小黑') #批量修改 51 # models.Article.objects.all().update(title='全部修改')#全部修改 52 53 #刪除 54 # Category.objects.all().delete()#刪除全表 55 #刪除某條資料 56 # obj = Category.objects.get(id=3) 57 # obj.delete() 58 # obj.save() 59 #刪除部分資料 60 # Category.objects.filter(id__in=[3,4]).delete(is_delete=False) 61 62 63 # #外來鍵操作 64 # obj = models.Article.objects.get(id=1) 65 # obj.nav_id = 2 #獲取外來鍵資訊 66 # print(obj.nav.name) #獲取外來鍵資訊 67 # models.Article.objects.filter(nav__name='abc') #按照外來鍵的欄位篩選,外來鍵名稱__欄位名 68 69 #反向查詢 70 # art_obj = models.Article.objects.get(pk=1) 71 # nav_obj = models.Nav.objects.get(pk=2) 72 # print(nav_obj.article_set.filter())#外來鍵反向查詢 73 # print(nav_obj.article_set.count())#外來鍵反向查詢 74 # nav_obj.article_set.add(art_obj)#新增 75 # nav_obj.article_set.remove(art_obj)#刪除 76 # nav_obj.article_set.clear()#清空 77 78 #多對多 79 80 81 82 # models.CaseSet.objects.create(name='主流程用例',desc='主流程') 83 # models.CaseSet.objects.create(name='冒煙用例',desc='冒煙用例') 84 # 85 # models.Case.objects.create(title='登入') 86 # models.Case.objects.create(title='註冊') 87 # models.Case.objects.create(title='訂購') 88 # models.Case.objects.create(title='支付') 89 # models.Case.objects.create(title='充值') 90 # models.Case.objects.create(title='發貨') 91 92 # c1 = models.Case.objects.get(pk=1) 93 # c2 = models.Case.objects.get(pk=2) 94 # c3 = models.Case.objects.get(pk=3) 95 # s1 = models.CaseSet.objects.get(pk=1) 96 # s2 = models.CaseSet.objects.get(pk=2) 97 98 # s2.case_set.add(c2,c3) 99 # s2.case_set.remove(c2,c3) 100 # s2.case_set.clear()#清空 101 102 # print(c2.case_set.all()) #檢視用例在幾個集合裡面 103 # print(s2.case_set.all()) #檢視集合裡面有多少用例 104 105 106 107 #一對一 108 #from hashlib import md5 109 #models.Account.objects.create(account_id=md5('niuhanyang'.encode()).hexdigest()) 110 #models.Account.objects.create(account_id=md5('niuhanyang2'.encode()).hexdigest()) 111 #models.Account.objects.create(account_id=md5('niuhanyang3'.encode()).hexdigest()) 112 113 # models.User.objects.create(username='niuhanyang',password='123456',account_id='58e006ecfce801c5e98311c96d32510f') 114 # u = models.User.objects.get(pk=1) 115 # print(u.account_id) 116 # print(u.account.money) 117 # 118 # acc = models.Account.objects.get(pk='58e006ecfce801c5e98311c96d32510f') 119 # print(acc.user.username) 120 # print(acc.user.password)
表結構如下圖:
一對一,user表和account表
nav表,外來鍵,一對多
case表和case_set表