django ORM基本配置
django中遵循 Code Frist 的原則,即:根據代碼中定義的類來自動生成數據庫表
1.修改project數據庫配置
(1)settigs.py里面
默認
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
修改為mysql數據庫:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysql', #數據庫名字 'USER': 'root', #賬號 'PASSWORD': '123456', #密碼 'HOST': '192.168.43.128', #IP 'PORT': '3306', #端口 } }
(2)把模塊改成pymysql
修改project目錄下的init.py
import pymysql pymysql.install_as_MySQLdb()
2.創建數據庫表結構文件
對應app目錄下的models.py
(1)生成一個簡單的數據庫表:
from django.db import models class UseInfo(models.Model): username = models.CharField(max_length=32) passwd = models.CharField(max_length=64) # 數據庫默認創建id列 自增 主鍵 # 用戶名列 字符串類型 字符長度
(2)把app名稱加入到settings里面
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'cmdb', # 系統會加載cmdb下的model.py文件 ]
(3)執行命令生成到數據庫
python manage.py makemigrations python manage.py migrate # 生成數據表
3.數據庫字段和字段參數

1、models.AutoField 自增列 = int(11) 如果沒有的話,默認會生成一個名稱為 id 的列,如果要顯示的自定義一個自增列,必須將給列設置為主鍵 primary_key=True。 2、models.CharField 字符串字段 必須 max_length 參數 3、models.BooleanField 布爾類型=tinyint(1) 不能為空,Blank=True 4、models.ComaSeparatedIntegerField 用逗號分割的數字=varchar 繼承CharField,所以必須 max_lenght 參數 5、models.DateField 日期類型 date 對於參數,auto_now = True 則每次更新都會更新這個時間;auto_now_add 則只是第一次創建添加,之后的更新不再改變。 6、models.DateTimeField 日期類型 datetime 同DateField的參數 7、models.Decimal 十進制小數類型 = decimal 必須指定整數位max_digits和小數位decimal_places 8、models.EmailField 字符串類型(正則表達式郵箱) =varchar 對字符串進行正則表達式 9、models.FloatField 浮點類型 = double 10、models.IntegerField 整形 11、models.BigIntegerField 長整形 integer_field_ranges = { 'SmallIntegerField': (-32768, 32767), 'IntegerField': (-2147483648, 2147483647), 'BigIntegerField': (-9223372036854775808, 9223372036854775807), 'PositiveSmallIntegerField': (0, 32767), 'PositiveIntegerField': (0, 2147483647), } 12、!models.IPAddressField 字符串類型(ip4正則表達式)不再使用 13、models.GenericIPAddressField 字符串類型(ip4和ip6是可選的) 參數protocol可以是:both、ipv4、ipv6 驗證時,會根據設置報錯 14、models.NullBooleanField 允許為空的布爾類型 15、models.PositiveIntegerFiel 正Integer 16、models.PositiveSmallIntegerField 正smallInteger 17、models.SlugField 減號、下划線、字母、數字 18、models.SmallIntegerField 數字 數據庫中的字段有:tinyint、smallint、int、bigint 19、models.TextField 字符串=longtext 20、models.TimeField 時間 HH:MM[:ss[.uuuuuu]] 21、models.URLField 字符串,地址正則表達式 22、models.BinaryField 二進制 23、models.ImageField 圖片 24、models.FilePathField 文件 所有字段...

null -> db是否可以為空 default -> 默認值 primary_key -> 主鍵 db_column -> 列名 db_index -> 索引 unique -> 唯一索引 unique_for_date -> unique_for_month unique_for_year auto_now -> 更新時,自動更新為當前時間 auto_now_add -> 創建時,自動生成時間 choices -> django admin中顯示下拉框,避免連表查詢 blank -> django admin是否可以為空 verbose_name -> django admin顯示字段中文 editable -> django admin是否可以被編輯 error_messages -> 錯誤信息欠 help_text -> django admin提示 validators -> django form, 自定義錯誤信息(欠) 所有字段參數...
數據庫基本操作
1.增加數據
(1)最常用的方式
from cmdb import models def userinfo(request): models.UseInfo.objects.create(username='derek',passwd='666') return HttpResponse('這種最常用')
(2)第二種跟第一種差不多
def userinfo(request): # models.UseInfo.objects.create(username='derek',passwd='666') # return HttpResponse('這種最常用') dicts = {'username':'jack','passwd':'999'} models.UseInfo.objects.create(**dicts) return HttpResponse('第二種跟第一種差不多')
(3)第三種
def userinfo(request): obj = models.UseInfo(username='tom',passwd='333') obj.save() return HttpResponse('第三種')
2.查詢數據
(1)查詢所有
def select(request): result = models.UseInfo.objects.all() print(result) #QuerySetL類型 for row in result: print(row.id,row.username,row.passwd) return HttpResponse('select')
(2)查詢指定字段
def select(request): result = models.UseInfo.objects.filter(username='derek') if result: for row in result: print(row.id,row.username,row.passwd) return HttpResponse('select')
3.刪除數據
def select(request): models.UseInfo.objects.filter(id=3).delete() return HttpResponse('select')
4.更新數據
def select(request): models.UseInfo.objects.filter(id=2).update(passwd='8888') return HttpResponse('select')
數據庫一對多操作
1.數據表結構
from django.db import models class UseGroup(models.Model): uid = models.AutoField(primary_key=True) #主鍵,自增 caption = models.CharField(max_length=32,unique=True) #唯一索引 ctime = models.DateField(auto_now_add=True,null=True) #創建時生成時間 uptime = models.DateField(auto_now=True,null=True) #更新時自動更新時間 class UseInfo(models.Model): username = models.CharField(max_length=32) passwd = models.CharField(max_length=64) # 關聯外鍵,生成字段名為user_group_id user_group = models.ForeignKey("UseGroup",to_field="uid",default=1)
2.外鍵關聯添加數據
from django.shortcuts import render,HttpResponse from app01 import models def add(request): ug_obj = models.UseGroup.objects.create(caption = "外鍵數據添加") # 把外鍵ug_obj當參數傳入 models.UseInfo.objects.create(username='derek',passwd='123',user_group=ug_obj) return HttpResponse('11')
3.外鍵關聯表操作
from django.shortcuts import render,HttpResponse from app01 import models # def add(request): # ug_obj = models.UseGroup.objects.create(caption = "外鍵數據添加") # # 把外鍵ug_obj當參數傳入 # models.UseInfo.objects.create(username='derek',passwd='123',user_group=ug_obj) # return HttpResponse('11') def ormadd(request): models.UseInfo.objects.create(username='jack',passwd='456') return HttpResponse('22') def ormgroup(request): models.UseGroup.objects.create(caption='CEO') return HttpResponse('33') def userinfo(request): obj = models.UseInfo.objects.all().first() print(obj.id,obj.username,obj.user_group_id) print(obj.user_group.uid,obj.user_group.caption) return HttpResponse('44')
返回結果:
4.跨表查詢使用雙下划綫 "__"
from django.db import models class Business(models.Model): caption = models.CharField(max_length=32) code = models.CharField(max_length=32,null=True,default='QA') class Host(models.Model): nid = models.AutoField(primary_key=True) hostname = models.CharField(max_length=32,db_index=True) ip = models.GenericIPAddressField(protocol='ipv4',db_index=True) port = models.IntegerField() b = models.ForeignKey(to='Business',to_field='id')
獲取表單數據
from django.shortcuts import render,HttpResponse from app01 import models def home(request): v2 = models.Host.objects.filter(nid=1).values('nid','hostname','b_id','b__caption') print(v2) return HttpResponse('33')
<QuerySet [{'nid': 1, 'hostname': 'c1.com', 'b_id': 1, 'b__caption': '運維'}]>
實例(一) 模板中顯示數據庫內容的方法
創建數據庫
from django.db import models from django.db import models class Business(models.Model): caption = models.CharField(max_length=32) code = models.CharField(max_length=32) class Host(models.Model): nid = models.AutoField(primary_key=True) hostname = models.CharField(max_length=32,db_index=True) ip = models.GenericIPAddressField(protocol='both',db_index=True) port = models.IntegerField() business = models.ForeignKey(to='Business',to_field='id',on_delete=models.CASCADE)

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>業務線列表(對象)</h1> <ul> {% for row in v1 %} <li>{{ row.id }}-{{ row.caption }}-{{ row.code }}</li> {% endfor %} </ul> <h1>業務線列表(字典)</h1> <ul> {% for row2 in v2 %} <li>{{ row2.id }}-{{ row2.caption }}</li> {% endfor %} </ul> </body> </html>

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>主機列表(對象)</h1> <table border="1"> <tread> <tr> <th>主機ID</th> <th>IP</th> <th>端口</th> <th>業務線名稱</th> </tr> </tread> <tbody> {% for row in v1 %} <tr> <td>{{ row.hostname }}</td> <td>{{ row.ip }}</td> <td>{{ row.port }}</td> <td>{{ row.business.caption }}</td> </tr> {% endfor %} </tbody> </table> <h1>主機列表(字典)</h1> <table border="1"> <tread> <tr> <th>主機ID</th> <th>主機名</th> <th>業務線ID</th> <th>業務線名稱</th> </tr> </tread> <tbody> {% for row in v2 %} <tr> <td>{{ row.nid }}</td> <td>{{ row.hostname }}</td> <td>{{ row.business__id }}</td> <td>{{ row.business__caption }}</td> </tr> {% endfor %} </tbody> </table> <h1>主機列表(元祖)</h1> <table border="1"> <tread> <tr> <th>主機ID</th> <th>主機名</th> <th>業務線ID</th> <th>業務線名稱</th> </tr> </tread> <tbody> {% for row in v3 %} <tr> <td>{{ row.0 }}</td> <td>{{ row.1 }}</td> <td>{{ row.2 }}</td> <td>{{ row.3 }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
from django.shortcuts import render,HttpResponse from app01 import models def business(request): # 第一種方式(是個對象) v1 = models.Business.objects.all() # 第二種方式,只取id和caption(是個字典) v2 = models.Business.objects.all().values('id','caption') return render(request,'business.html',{'v1':v1,'v2':v2}) def host(request): #總共三種方式,對象,字典,列表 v1 = models.Host.objects.all() v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','business__id','business__caption') v3 = models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','business__id','business__caption') return render(request,'host.html',{'v1':v1,'v2':v2,'v3':v3})
實例(二) 一對多
1.創建
from django.db import models class UserType(models.Model): title = models.CharField(max_length=32) class UserInfo(models.Model): name = models.CharField(max_length=16) age = models.IntegerField() ut = models.ForeignKey('UserType')
from django.shortcuts import render,HttpResponse from app01 import models def add(request): models.UserType.objects.create(title='普通用戶') models.UserType.objects.create(title='黃金用戶') models.UserType.objects.create(title='白金用戶') models.UserInfo.objects.create(name='aa', age=18, ut_id=1) models.UserInfo.objects.create(name='bb', age=18, ut_id=2) models.UserInfo.objects.create(name='cc', age=18, ut_id=2) return HttpResponse('ok')
2.操作
(1)查詢所有用戶和類型
def op(request): obj = models.UserInfo.objects.all() for row in obj: print(row.name,row.age,row.ut.title) return HttpResponse('ok') #查看所有 aa 18 普通用戶 bb 18 黃金用戶 cc 18 黃金用戶 #查看第一條 obj = models.UserInfo.objects.all().first() print(obj.name, obj.age, obj.ut.title) aa 18 普通用戶
(2)查詢所有類型為“黃金用戶的”用戶
正向查
#這里跨表查詢要用到雙下划線"__"
result = models.UserInfo.objects.filter(ut__title='黃金用戶') for item in result: print(item.name,item.age,item.ut.title) 結果: bb 18 黃金用戶 cc 18 黃金用戶
反向查
obj = models.UserType.objects.get(id=2) result = obj.userinfo_set.all() #這里的userinfo_set相當於models.UserInfo.objects.filter(ut="黃金用戶") for item in result: print(item.name,item.age,item.ut.title) 結果: bb 18 黃金用戶 cc 18 黃金用戶
還可以加條件過濾
obj = models.UserType.objects.get(id=2) result = obj.userinfo_set.filter(name='bb') #這里的userinfo_set相當於models.UserInfo.objects.filter(ut="黃金用戶") for item in result: print(item.name,item.age,item.ut.title) 結果: bb 18 黃金用戶
數據庫多對多操作
1.自動方式創建第三張表
(1)創建管理用戶和主機兩張表,自動生成第三張關系表
from django.db import models class Host(models.Model): hostname = models.CharField(max_length=32) port = models.IntegerField() class HostAdmin(models.Model): username = models.CharField(max_length=32) email = models.CharField(max_length=32) host = models.ManyToManyField('Host')
(2)添加主機信息和管理用戶信息
#添加主機信息 def add_host(request): models.Host.objects.create(hostname='host1',port=80) models.Host.objects.create(hostname='host2',port=80) models.Host.objects.create(hostname='host3',port=80) models.Host.objects.create(hostname='host4',port=80) return HttpResponse('ok') #添加管理用戶信息 def add_hostadmin(request): models.HostAdmin.objects.create(username='aa',email='11.com') models.HostAdmin.objects.create(username='bb',email='22.com') models.HostAdmin.objects.create(username='cc',email='33.com') models.HostAdmin.objects.create(username='dd',email='44.com') return HttpResponse('ok')
效果如下:
(3)添加第三張關系表
正向添加數據
#添加第三張表信息,使管理用戶與主機關聯 def user_info(request): # 第一步找到用戶 admin_obj = models.HostAdmin.objects.get(username='bb') #第二步找到主機 host_list = models.Host.objects.filter(id__lt=3) #第三步,通過找到的admin_obj對象.add去添加主機 admin_obj.host.add(*host_list) return HttpResponse('ok')
效果如下:
用戶‘’bb“(用戶id=2)就跟主機‘1’和‘2’(主機id=(1,2))關聯起來了
反向添加數據
def user_info(request): host_obj = models.Host.objects.get(id=3) admmin_list = models.HostAdmin.objects.filter(id__gt=1) host_obj.hostadmin_set.add(*admmin_list) return HttpResponse('ok')
效果如下:
總之,不管是正向添加還是反向添加,都是基於主機表或者用戶表的一行數據對應另一張表中的一行或多行數據!
2.手動方式創建第三張表
(1)創建
手動創建就是告訴django不要自動創建表了
from django.db import models class HostInfo(models.Model): hostname = models.CharField(max_length=32) port = models.IntegerField() class UserMap(models.Model): username = models.CharField(max_length=32) email = models.CharField(max_length=32) # through告訴Django用那張表做關聯 host = models.ManyToManyField(HostInfo, through='HostRelation') class HostRelation(models.Model): host = models.ForeignKey('HostInfo') user = models.ForeignKey('UserMap')
效果如下:
(2)添加用戶和主機
from django.shortcuts import render,HttpResponse from app02 import models def user_info(request): models.HostInfo.objects.create(hostname='host1',port=80) models.HostInfo.objects.create(hostname='host2',port=80) models.HostInfo.objects.create(hostname='host3',port=80) models.HostInfo.objects.create(hostname='host4',port=80) models.UserMap.objects.create(username='aa',email='11.com') models.UserMap.objects.create(username='bb',email='22.com') models.UserMap.objects.create(username='cc',email='33.com') models.UserMap.objects.create(username='dd',email='44.com') return HttpResponse('ok')
(3)給第三張表添加數據
當使用自定義方式時,第三張關系表數據直接添加就可以,不需要管另外兩張表
def user_info(request): models.HostRelation.objects.create( host_id = 2, user_id = 2 ) return HttpResponse('ok')
效果:

models.HostRelation.objects.create( host_id = 1, user_id = 1 ) models.HostRelation.objects.create( host_id=3, user_id=1 )
(4)查找
通過自定義方式,查找直接查就可以,不存在正向反向,更方便
def user_info(request): relation_list = models.HostRelation.objects.all() for item in relation_list: print(item.user.username) print(item.host.hostname) return HttpResponse('ok')
結果:
bb
host2
aa
host1
aa
host3
def user_info(request): relation_list = models.HostRelation.objects.filter(user__username='bb') for item in relation_list: print(item.user.username) print(item.host.hostname) return HttpResponse('ok')
ORM的F&Q
1.F
F的作用:用來批量修改數據的
比如:把上面hostinfo表所有port從80改成90
models.HostInfo.objects.all().update(port=F('port')+10)
要先導入模塊
from django.db.models import F
2.Q
Q的作用:Q是用來做條件查詢的