1. 程式人生 > 實用技巧 >Django學習筆記(3)orm模型操作

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表