您好,登錄后才能下訂單哦!
本篇內容接上篇Python基礎(Django二)
七、Model
1、說明:
Model是Django為方便程序操作數據庫而誕生的,使用的是ORM模式。
對象關系映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術。簡單的說,ORM是通過使用描述對象和數據庫之間映射的關系,將程序中的對象自動持久化到關系數據庫中。
2、使用:
2-1、創建Model(編輯應用目錄下的models.py)
from django.db import models class Author(models.Model): #定義一個類(表),類名即是表名 #定義一個叫first_name的字段(列),字段類型為字符串類型,參數設置最大長度為32個字節 first_name = models.CharField(max_length=32) last_name = models.CharField(max_length=32) email = models.EmailField(null=True,blank=True) #字段類型為郵箱,會有格式驗證 def __unicode__(self): #定義查詢類的數據時顯示的值 return '%s %s'%(self.first_name,self.last_name)
字段類型:
1、models.AutoField 自增列 = int(11)
如果沒有的話,默認會生成一個名稱為 id 的列,如果要顯示的自定義一個自增列,必須將給列設置為主鍵 primary_key=True。
2、models.CharField 字符串字段
必須 max_length 參數
3、models.BooleanField 布爾類型 =tinyint(1)
不能為空
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 文件
參數:
1、null=True
數據庫中字段是否可以為空
2、blank=True
django的 Admin 中添加數據時是否可允許空值
3、primary_key = False
主鍵,對AutoField設置主鍵后,就會代替原來的自增 id 列
4、auto_now 和 auto_now_add
auto_now 自動創建---無論添加或修改,都是當前操作的時間
auto_now_add 自動創建---永遠是創建時的時間
5、choices
GENDER_CHOICE = (
(u'M', u'Male'),
(u'F', u'Female'),
)
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default 默認值
8、verbose_name Admin中字段的顯示名稱
9、name|db_column 數據庫中的字段名稱
10、unique=True 不允許重復
11、db_index = True 數據庫索引
12、editable=True 在Admin里是否可編輯
13、error_messages=None 錯誤提示
14、auto_created=False 自動創建
15、help_text 在Admin中提示幫助信息
16、validators=[]
17、upload-to
#相關命令
python manage.py validate #用來檢測models.py語法的正確性
python manage.py makemigrations
python manage.py migrate #根據代碼中定義的類來自動創建數據庫表
2-2、操作數據庫表
from app01 import models # 增 # #第一種: models.Author.objects.create(first_name='zhang',last_name='san',email='z@test.com') #第二種:可以接受字典類型的數據 dic = {'first_name': 'li', 'last_name': 'si', 'email': 'z@test.com'} models.Author.objects.create(**dic) #第三種: obj = models.Author(**dic) obj.save() # 查 # models.Author.objects.all() #獲取Author表里的所有數據 #過濾查詢 filter()方法獲取的是一個列表,get()方法獲取的是單個對象 models.Author.objects.get(first_name='zhang') #Author是表名稱,first_name是字段名稱,zhang是查詢的關鍵字 models.Author.objects.filter(last_name='san') models.Author.objects.filter(first_name='zhang', last_name='san') #查詢條件可以有多個 models.Author.objects.exclude(first_name='zhang') #查詢first_name不等于zhang的 models.Author.objects.filter(first_name='zhang').count() #獲取滿足查詢條件的數據個數 #多重查詢 models.Author.objects.filter(first_name='zhang').order_by("email") #限制查詢 models.Author.objects.order_by('first_name')[0] #取查詢結果QuerySet的第一個值 #排序 models.Author.objects.order_by("first_name") #根據某一個字段值對結果排序 models.Author.objects.order_by("first_name","last_name") #根據多個字段排序,第二個字段會在第一個字段值相同的情況下被使用到 models.Author.objects.order_by("-first_name") #逆向排序,字段前面加減號-前綴 #利用雙下劃線將查詢字段和相應操作連接起來(摘自其他博客) # 大于,小于 models.Tb1.objects.filter(id__gt=1) # 獲取id大于1的值 models.Tb1.objects.filter(id__lt=10) # 獲取id小于10的值 models.Tb1.objects.filter(id__lt=10, id__gt=1) # 獲取id大于1 且 小于10的值 # in models.Tb1.objects.filter(id__in=[11, 22, 33]) # 獲取id等于11、22、33的數據 models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in # contains models.Tb1.objects.filter(name__contains="ven") #用于模糊匹配name字段。 models.Tb1.objects.filter(name__icontains="ven") #icontains大小寫不敏感 models.Tb1.objects.exclude(name__icontains="ven") #取反 # range models.Tb1.objects.filter(id__range=[1, 2]) # 范圍bettwen and # 改 # # 在查詢的基礎上增加一個修改操作 # 第一種: models.Author.objects.filter(last_name='si').update(last_name='SI') # 第二種:可以接受字典類型的數據 dic = {'first_name': 'li', 'last_name': 'si', 'email': 'z@test.com'} models.Author.objects.filter(last_name='si').update(**dic) # 第三種: obj = models.Author.objects.get(last_name='si') obj.email = 'new@test.com' obj.save() # 刪 # # 在查詢的基礎上增加一個刪除操作 models.Author.objects.filter(last_name='san').delete()
2-3、連表結構
說明:
Django的ORM有多種關系:
一對一:一個只屬于一個
一對多:一個屬于多個
多對多:一個既有很多個,又屬于很多個
各自定義的方式為 :
一對一: models.OneToOneField(其他表)
一對多: models.ForeignKey(其他表)
多對多: models.ManyToManyField(其他表)
應用場景:
一對多:當一張表中創建一行數據時,有一個單選的下拉框(可以被重復選擇)
例如:創建用戶信息時候,需要選擇一個用戶類型【普通用戶】【金牌用戶】【鉑金用戶】等。
多對多:在某表中創建一行數據是,有一個可以多選的下拉框
例如:創建用戶信息,需要為用戶指定多個愛好
一對一:在某表中創建一行數據時,有一個單選的下拉框(下拉框中的內容被用過一次就消失了
舉例:
#models.py
# -*- coding:utf-8 -*- from __future__ import unicode_literals from django.db import models # Create your models here. # OneToMany example 1 class UserType(models.Model): caption = models.CharField(max_length=32) def __unicode__(self): return self.caption class UserInfo(models.Model): user_type = models.ForeignKey(UserType) username = models.CharField(max_length=32) age = models.IntegerField() def __unicode__(self): return self.username # OneToMany example 2 class MyUser(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=16) def __unicode__(self): return self.username class News(models.Model): title = models.CharField(max_length=32) content = models.CharField(max_length=32) def __unicode__(self): return self.title class Favor(models.Model): user_obj = models.ForeignKey(MyUser) new_obj = models.ForeignKey(News) def __unicode__(self): return "%s --> %s"%(self.user_obj.username,self.new_obj.title) # ManyToMany example 1 class Host(models.Model): hostname = models.CharField(max_length=32) port = models.IntegerField() def __unicode__(self): return self.hostname class HostAdmin(models.Model): username = models.CharField(max_length=32) email = models.CharField(max_length=32) host = models.ManyToManyField(Host) def __unicode__(self): return self.username # ManyToMany example 2 '''手動創建多對多關系表,不需要Django自動創建,優點是第三張表的字段可以自定義''' class Host2(models.Model): hostname = models.CharField(max_length=32) port = models.IntegerField() def __unicode__(self): return self.hostname class HostAdmin2(models.Model): username = models.CharField(max_length=32) email = models.CharField(max_length=32) host = models.ManyToManyField(Host2,through="HostRelation") def __unicode__(self): return self.username class HostRelation(models.Model): host_obj = models.ForeignKey(Host2) admin_obj = models.ForeignKey(HostAdmin2)
#views.py
# -*- coding:utf-8 -*- from django.shortcuts import render,HttpResponse from app01 import models # Create your views here. def user_info(request): # 一對多 # # models 為"OneToMany example 1" #創建數據# #第一種: ForeignKey所在的字段加 _id 進行直接賦值 models.UserInfo.objects.create(username='test1',age=13,user_type_id=1) #user_type_id是一對多關系表中Django自動生成的字段名 #第二種:ForeignKey所在的字段使用對象進行賦值 user_type_obj = models.UserType.objects.get(id=2) #先從user_type表中獲取一個對象 models.UserInfo.objects.create(username='test2',age=14,user_type=user_type_obj) #使用剛獲取的對象進行賦值(注意字段名稱) #正向查找#(就是從ForeignKey所在字段的表去查詢數據) #單表查詢 models.UserInfo.objects.filter(username='test1') #查詢UserInfo表中username字段值是‘test1’的數據 # 跨表查詢,通過ForeignKey所在的字段 + 雙下劃線 + 被跨的表中的字段來查詢(ForeignKey所在的字段user_type是一個對象) # models.UserInfo.objects.filter(user_type__caption='CEO') #查詢UserInfo表中user_type對象中caption字段的值是CEO的數據 ret = models.UserInfo.objects.filter(user_type__id=2) #語法同上,ret是一個QuerySet對象 for i in ret: #打印獲取到的QuerySet對象中每個值的username屬性,以及user_type對象的caption屬性(跨表操作時,查詢使用__(雙下劃線),訪問字段使用.(點)) print i.username,i.user_type.caption #反向查找#(就是從被ForeignKey字段關聯的表去查詢數據) #單表查詢 line = models.UserType.objects.get(id=1) #從UserType表中獲取一個id=1的對象 #跨表查詢 # 第一種: 通過被跨的表的小寫表名 + 雙下劃線 + 要查詢的字段 來查詢 models.UserType.objects.get(userinfo__username='test1') #userinfo是django自動在UserType表中創建的一個對象,也就是對端表的小寫表名 # 第二種: line.userinfo_set.filter(username='test1') # line是一個對象(參考如上的獲取條件) # userinfo_set是UserInfo表中滿足line條件的所有值。也就是UserInfo表中所有user_type=1 的值 # 本次查詢的目標是:通過UserType表去反向查詢UserInfo表中user_type=1且username=test1的所有數據 line.userinfo_set.all().count() #計算滿足查詢條件的數據個數 #多級查詢, models 為"OneToMany example 2" ret = models.News.objects.filter(favor__user_obj__username='zhangsan') # 查詢的表順序為 News -> Favor -> MyUser # 先是反向跨表查詢:通過News表查詢Favor表中的user_obj對象 # 再是正向跨表查詢:通過user_obj對象查詢Myuser表中username字段值為zhangsan的用戶 # 最終得到zhangsan贊過的所有文章 for i in ret: print i.title #文章的標題 print i.favor_set.all().count() #文章一共幾個贊 # 多對多 # # models為 "ManyToMany example 1" models.HostAdmin.objects.create(username='a1',email='1@qq.com') #創建一個用戶,管理的主機為空 #正向添加# admin_obj = models.HostAdmin.objects.get(username='a1') #先獲取一個用戶對象 host_list = models.Host.objects.filter(id__lt=3) #再獲取多個主機對象 admin_obj.host.add(*host_list) #為一個用戶添加多個可管理的主機 #反向添加# host_obj = models.Host.objects.get(hostname='h2') #先獲取一個主機對象 admin_list = models.HostAdmin.objects.filter(id__gt=1) #再獲取多個用戶對象 host_obj.hostadmin_set.add(*admin_list) #為一個主機添加多個用戶,注意這里用到了hostadmin_set #正向查詢# admin_obj = models.HostAdmin.objects.get(username='a1') #先獲取一個用戶對象 host_list = admin_obj.host.all() #查詢該用戶管理的所有主機 for i in host_list: print i.hostname,i.port #反向查詢# host_obj = models.Host.objects.get(hostname='h2') #先獲取一個主機對象 admin_list = host_obj.hostadmin_set.all() #查詢該主機的所有管理員 for i in admin_list: print i.username,i.email #自定義多對多關系# # models為 "ManyToMany example 2" # 添加數據 models.HostRelation.objects.create( host_obj_id = 1, #等于 host_obj = models.Host2.objects.get(id=1) admin_obj_id = 1, #等于 admin_obj = models.HostAdmin2.objects.get(id=1) ) # 查詢 # relation_list = models.HostRelation.objects.all() relation_list = models.HostRelation.objects.filter(admin_obj__username='user1') #通過HostRelation表查詢用戶名是user1的所有數據 for i in relation_list: print i.admin_obj.username #用戶名 print i.host_obj.hostname #用戶所管理主機的主機名 # Django 的F # # 對對象中某一列值的操作 from django.db.models import F models.Host.objects.filter(hostname='h2').update(port=F('port')+1) #把Host表中所有hostname=h2的數據的port值加1 models.Host.objects.update(port=F('port')+1) #把Host表中所有的port值加1 # Django 的Q # # 對象的復雜查詢 from django.db.models import Q #單Q多條件查詢 q1 = Q() #創建一個Q對象 q1.connector = 'OR' #定義查詢條件是 '或' q1.children.append(('hostname__contains','h2')) #children添加的是元祖,查詢字段支持使用一些自帶的方法 q1.children.append(('hostname','h3')) #添加多個查詢條件 q1.children.append(('hostname','h6')) ret_list = models.Host.objects.filter(q1) #使用q1對象進行查詢(針對Host表) for i in ret_list: print '%s->%s'%(i.hostname,i.port) #多Q多條件查詢 con = Q() #創建一個外層Q對象,Q可以嵌套 q2 = Q() q2.connector = 'OR' q2.children.append(('port','23')) #查詢port字段值等于23的數據 q2.children.append(('port__gt','23')) #查詢port字段值大于23的數據 con.add(q1,'AND') #把q1添加到之前定義的最外層的Q對象中,查詢條件是 '和' con.add(q2,'AND') #把q2添加到之前定義的最外層的Q對象中,查詢條件是 '和' ret_list = models.HostAdmin.objects.filter(con) #查詢的結果是同時滿足q1和q2條件的數據(針對HostAdmin表) for i in ret_list: print '%s->%s'%(i.hostname,i.port) #多Q多條件跨表查詢 q1.children.append(('username','a1')) q1.children.append(('username','a2')) q1.children.append(('username','a3')) q2.children.append(('host__hostname','h5')) #支持跨表查詢,host是表名 + 雙下劃線 + 查詢的字段 con.add(q1,'AND') con.add(q2,'AND') ret_list = models.HostAdmin.objects.filter(con) #查詢用戶名是a1或a2或a3 且管理主機名為h5的用戶(針對HostAdmin表) for i in ret_list: print i.username return HttpResponse('ok') #無特別意義,只是函數需要一個返回值。
博客的部分內容和思路整理自武沛齊的博客。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。