model是關於你的數據的單一的,肯定的信息來源。 它包含您正在存儲的數據的基本字段和行爲。Django經過抽象化的模型層(models)爲你的網絡應用提供對於數據的結構化處理和操做處理,數據庫相關的代碼通常寫在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等數據庫,使用數據庫API對數據庫進行增刪改查的操做。python
使用哪一種數據庫,只須要在settings.py中配置便可,如:mysql
<1> sqlite: django默認使用sqlite的數據庫,默認自帶sqlite的數據庫驅動 , 引擎名稱:django.db.backends.sqlite3 git
<2> mysql:引擎名稱:django.db.backends.mysqlsql
<3>若是想更改數據庫:shell
1 DATABASES = { 2 'default': { 3 'ENGINE': 'django.db.backends.mysql', 4 'NAME': 'books', #你的數據庫名稱
5 'USER': 'root', #你的數據庫用戶名
6 'PASSWORD': '', #你的數據庫密碼
7 'HOST': '', #你的數據庫主機,留空默認爲localhost
8 'PORT': '3306', #你的數據庫端口
9 } 10
11 }
注意事項:數據庫
1 NAME即數據庫的名字,在mysql鏈接前該數據庫必須已經建立,而上面的sqlite數據庫下的db.sqlite3則是項目自動建立 2 USER和PASSWORD分別是數據庫的用戶名和密碼。 3 設置完後,再啓動咱們的Django項目前,咱們須要激活咱們的mysql。 4 而後,啓動項目,會報錯:no module named MySQLdb 5 這是由於django默認你導入的驅動是MySQLdb,但是MySQLdb對於py3有很大問題,因此咱們須要的驅動是PyMySQL 6
7 因此,咱們只須要找到項目名文件下的__init__,在裏面寫入: 8 import pymysql 9 pymysql.install_as_MySQLdb()
Model 字段django
1 AutoField 根據實際ID自動增加的IntegerField . 你一般不須要直接使用; 2 若是不指定,一個主鍵字段將自動添加到你建立的 3 BigIntegerField 一個64位整數, 相似於一個 IntegerField 這個字段默認的表單組件是一個TextInput. 4
5 IntegerField([**options]) 6 一個整數。在Django所支持的全部數據庫中,從 -2147483648 到 2147483647 範圍內的值是合法的。默認的表單輸入工具是TextInput. 7
8 BinaryField 用來存儲原始二進制碼的Field. 只支持bytes 賦值,注意這個Field只有頗有限的功能。 9 例如,不大可能在一個BinaryField 值的數據上進行查詢 10 BooleanField true/false 字段。默認表單掛件是一個CheckboxInput. 11 若是你須要設置null 值,則使用NullBooleanField 來代替BooleanField。 12 若是Field.default沒有指定的話, BooleanField 的默認值是 None。 13 CharField 一個用來存儲從小到很大各類長度的字符串的地方。 14 若是是巨大的文本類型, 能夠用 TextField. 15 這個字段默認的表單樣式是 TextInput. 16 CharField必須接收一個額外的參數: 17 CharField.max_length¶:字段的最大字符長度.max_length將在數據庫層和Django表單驗證中起做用, 用來限定字段的長度. 18 DateField 這是一個使用Python的datetime.date實例表示的日期. 有幾個額外的設置參數: 19
20 DateField.auto_now¶ 每次保存對象時,自動設置該字段爲當前時間。 21 用於"最後一次修改"的時間戳。注意,它老是使用當前日期;它不僅是一個默認值,你能夠覆蓋。 22
23 DateField.auto_now_add¶ 當對象第一次被建立時自動設置當前時間。用於建立時間的時間戳. 24 它老是使用當前日期;和你能夠覆蓋的那種默認值不同。 25
26 該字段默認對應的表單控件是一個TextInput. 在管理員站點添加了一個JavaScript寫的日曆控件, 27 和一個「Today"的快捷按鈕.包含了一個額外的invalid_date錯誤消息鍵.
28
29
30 DateTimeField(DateField) - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 31
32 DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD 33
34 TimeField(DateTimeCheckMixin, Field) - 時間格式 HH:MM[:ss[.uuuuuu]] 35
36 DurationField(Field)用做存儲一段時間的字段類型 - 相似Python中的timedelta. 37 - 長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值爲datetime.timedelta類型 38
39 DecimalField(max_digits=None, decimal_places=None[, **options]) 表示十進制浮點數 40
41 EmailField([max_length=254, **options])一個 CharField 用來檢查輸入的email地址是否合法。它使用 EmailValidator 來驗證輸入合法性。 42
43 FileField([upload_to=None, max_length=100)一個上傳文件的字段。 44 FileField字段不支持primary_key 和unique參數,若是使用會生成 TypeError錯誤 45
46 FilePathField(path=None[, match=None, recursive=False, max_length=100]) 47 一個 CharField ,內容只限於文件系統內特定目錄下的文件名。有三個參數, 其中第一個是 必需的: 48
49 FloatField([**options])用Python的一個float 實例來表示一個浮點數. 50
51
52 ImageField([upload_to=None, height_field=None, width_field=None, max_length=100, **options])¶ 53 繼承了 FileField的全部屬性和方法, 但還對上傳的對象進行校驗,確保它是個有效的image. 54
55 TextField([**options])大文本字段。該模型默認的表單組件是Textarea。 56
57 TimeField([auto_now=False, auto_now_add=False, **options])¶ 58 時間字段,和Python中 datetime.time 同樣。接受與DateField相同的自動填充選項。 59 表單默認爲 TextInput.輸入框。 60
61 URLField([max_length=200, **options])一個CharField 類型的URL此字段的默認表單widget爲TextInput。 62
63 UUIDField([**options])一個用來存儲UUID的字段。使用Python的UUID類。 64 當使用PostgreSQL數據庫時,該字段類型對應的數據庫中的數據類型是uuid
1 Field.null 若是爲True,Django將在數據庫中將空值存儲爲NULL。默認值是 False。 2 3 Field.blank 若是爲True,則該字段容許爲空白。 默認值是 False。 4 5 Field.choices 它是一個可迭代的結構(好比,列表或是元組), 6 由可迭代的二元組組成(好比[(A, B), (A, B) ...]),用來給這個字段提供選擇項。 7 若是設置了 choices ,默認表格樣式就會顯示選擇框,而不是標準的文本框,並且這個選擇框的選項就是 choices 中的元組。 8 9 Field.db_column 數據庫中用來表示該字段的名稱。若是未指定,那麼Django將會使用Field名做爲字段名. 10 11 Field.db_index 若值爲 True, 則 django-admin sqlindexes 將會爲此字段輸出 CREATE INDEX 語句。 12 13 14 Field.error_messages 可以讓你重寫默認拋出的錯誤信息。經過指定 key 來確認你要重寫的錯誤信息。 15 16 Field.primary_key若爲 True, 則該字段會成爲模型的主鍵字段。 17 若是你沒有在模型的任何字段上指定 primary_key=True, Django會自動添加一個 AutoField 字段來充當主鍵。 18 19 Field.unique 若是爲 True, 這個字段在表中必須有惟一值. 20 21 Field.unique_for_month 相似unique_for_date,只是要求字段對於月份是惟一的。 22 23 驗證器 24 Field.validators 該字段將要運行的一個Validator 的列表。
元信息Meta——使用內部的class Meta 定義模型的元數據後端
from django.db import models class Ox(models.Model): horn_length = models.IntegerField() class Meta: ordering = ["horn_length"] verbose_name_plural = "oxen"
模型元數據是「任何不是字段的數據」,好比排序選項(ordering),數據表名(db_table)或者人類可讀的單複數名稱(verbose_name 和verbose_name_plural)。網絡
在模型中添加class Meta是徹底可選的,全部選項都不是必須的。
app
關係字段
關係數據庫的威力體如今表之間的相互關聯。
Django 提供了三種最多見的數據庫關係:多對一(manyto-one),多對多(many-to-many),一對一(one-to-one)。
多對一關係
Django 使用 django.db.models.ForeignKey 定義多對一關係。和使用其它字段類型同樣:在模型當中把它作爲一個類屬性包含進來。
ForeignKey 須要一個位置參數:與該模型關聯的類。
1 limit_choices_to 當這個字段使用模型表單或者Admin 渲染時(默認狀況下,查詢集中的全部對象均可以使用), 2 爲這個字段設置一個可用的選項。它能夠是一個字典、一個Q 對象或者一個返回字典或Q對象的可調用對象。 3 Q(caption='root') 4 db_constraint=True # 是否在數據庫中建立外鍵約束 5 parent_link=False # 在Admin中是否顯示關聯數據 6 7 related_name 這個名稱用於讓關聯的對象反查到源對象。它仍是related_query_name 的默認值(關聯的模型進行反向過濾時使用的名稱)。 8 9 related_query_name 這個名稱用於目標模型的反向過濾。若是設置了related_name,則默認爲它的值,不然默認值爲模型的名稱 10 11 to_field 關聯到的關聯對象的字段名稱。默認地,Django 使用關聯對象的主鍵。 12 13 db_constraint控制是否在數據庫中爲這個外鍵建立約束。默認值爲True 14 15 on_delete 當一個ForeignKey 引用的對象被刪除時,Django 默認模擬SQL 的ON DELETE CASCADE 的約束行爲,而且刪除包含該ForeignKey的對象。這種行爲能夠經過設置on_delete 參數來改變。 16 17 CASCADE級聯刪除;默認值。 18 19 PROTECT拋出ProtectedError 以阻止被引用對象的刪除,它是django.db.IntegrityError 的一個子類。 20 21 SET_NULL把ForeignKey 設置爲null; null 參數爲True 時才能夠這樣作。 22 23 SET_DEFAULT ForeignKey值設置成它的默認值;此時必須設置ForeignKey 的default 參數。 24 25 SET() 設置ForeignKey 爲傳遞給SET() 的值,若是傳遞的是一個可調用對象,則爲調用後的結果。 26 DO_NOTHING不採起任何動做。若是你的數據庫後端強制引用完整性,它將引起一個IntegrityError ,除非你手動添加一個ON DELETE 約束給數據庫自動
ManyToManyField一個多對多關聯。
要求一個關鍵字參數:與該模型關聯的類,與ForeignKey 的工做方式徹底同樣,包括遞歸關係 和惰性關係。
關聯的對象能夠經過字段的RelatedManager 添加、刪除和建立。
1 若是源模型和目標不一樣,則生成如下字段: 2 id:關係的主鍵。 3 <containing_model>_id:聲明ManyToManyField 字段的模型的id。 4 <other_model>_id:ManyToManyField 字段指向的模型的id。 5 6 若是ManyToManyField 的源模型和目標模型相同,則生成如下字段: 7 id:關係的主鍵。 8 from_<model>_id:源模型實例的id。 9 to_<model>_id:目標模型實例的id。 10 這個類可讓一個給定的模型像普通的模型那樣查詢與之相關聯的記錄。 11 12 to, # 要進行關聯的表名 13 related_name=None, # 反向操做時,使用的字段名,用於代替 【表名_set】 如: obj.表名_set.all() 14 related_query_name=None, # 反向操做時,使用的鏈接前綴,用於替換【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名') 15 16 limit_choices_to=None, # 在Admin或ModelForm中顯示關聯數據時,提供的條件: 17 # 如: 18 - limit_choices_to={'nid__gt': 5} 19 - limit_choices_to=lambda : {'nid__gt': 5} 20 21 from django.db.models import Q 22 - limit_choices_to=Q(nid__gt=10) 23 - limit_choices_to=Q(nid=8) | Q(nid__gt=10) 24 - limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root') 25 26 symmetrical=None,# 僅用於多對多自關聯時,symmetrical用於指定內部是否建立反向操做的字段 27 # 作以下操做時,不一樣的symmetrical會有不一樣的可選字段 28 models.BB.objects.filter(...) 29 30 # 可選字段有:code, id, m1 31 class BB(models.Model): 32 33 code = models.CharField(max_length=12) 34 m1 = models.ManyToManyField('self',symmetrical=True) 35 36 # 可選字段有: bb, code, id, m1 37 class BB(models.Model): 38 39 code = models.CharField(max_length=12) 40 m1 = models.ManyToManyField('self',symmetrical=False) 41 42 through=None, # 自定義第三張表時,使用字段用於指定關係表 43 through_fields=None, # 自定義第三張表時,使用字段用於指定關係表中那些字段作多對多關係表 44 from django.db import models 45 46 class Person(models.Model): 47 name = models.CharField(max_length=50) 48 49 class Group(models.Model): 50 name = models.CharField(max_length=128) 51 members = models.ManyToManyField( 52 Person, 53 through='Membership', 54 through_fields=('group', 'person'), 55 ) 56 57 class Membership(models.Model): 58 group = models.ForeignKey(Group, on_delete=models.CASCADE) 59 person = models.ForeignKey(Person, on_delete=models.CASCADE) 60 inviter = models.ForeignKey( 61 Person, 62 on_delete=models.CASCADE, 63 related_name="membership_invites", 64 ) 65 invite_reason = models.CharField(max_length=64) 66 67 db_constraint=True, # 是否在數據庫中建立外鍵約束 68 db_table=None, # 默認建立第三張表時,數據庫中表的名稱
一對一關聯關係。概念上講,這個字段很像是ForeignKey 設置了unique=True,不一樣的是它會直接返回關係另外一邊的單個對象。
它最主要的用途是做爲擴展自另一個模型的主鍵;例如,多表繼承就是經過對子模型添加一個隱式的一對一關聯關係到父模型實現的。
須要一個位置參數:與該模型關聯的類。 它的工做方式與ForeignKey 徹底一致,包括全部與遞歸關係和惰性關係相關的選項。
如下內容我的理解筆記:
class News(models.Model): title = models.CharField(max_length=10) favor = models.ManyToManyField('User',through="Favor",through_fields=("new_obj", 'user_obj'))
# obj = models.News.objects.get(id=1)
# v = obj.favor.all()
# print(v)
# obj.favor.add(1)不能用
# obj.favor.remove(1)不能用
# v = obj.favor.all()能用
# obj.favor.clear()能用,根據id刪,不用name這個字段
# v = models.User.objects.all()
# v = models.User.objects.all().select_related('user_type')class User(models.Model):
name = models.CharField(max_length=10) email = models.EmailField(max_length=10) user_type = models.ForeignKey('UserType') # 一對多 # user_profile = models.ForeignKey('UserDetail',unique=True) user_profile = models.OneToOneField('UserDetail') class UserDetail(models.Model): pwd = models.CharField(max_length=32) class Favor(models.Model): new_obj = models.ForeignKey('News',related_name="n") user_obj = models.ForeignKey('User',related_name='u') name = models.CharField(max_length=64,null=True,blank=True) class UserType(models.Model): name = models.CharField(max_length=10)
訪問外鍵(Foreign Key)值
python manage.py shell
當你獲取一個ForeignKey 字段時,你會獲得相關的數據模型對象。
>>> from django.db import connection
>>> from app01.models import User
>>> u=User.objects.get(id=1)
>>> u
<User: User object>
>>> u.user_type
<UserType: UserType object>
>>> u.user_type.name
'type1'
對於用ForeignKey 來定義的關係來講,在關係的另外一端也能反向的追溯回來,
經過一個UserType對象,直接獲取 user ,用 UserType.user_set.all() ,
實際上,user_set 只是一個 QuerySet(參考第5章的介紹),
因此它能夠像QuerySet同樣,能實現數據過濾和分切,屬性名稱user_set是由模型名稱的小寫加_set組成的。
>>> from app01.models import UserType
>>> t=UserType.objects.get(name='type1')
>>> t.user_set.all()
<QuerySet [<User: User object>, <User: User object>]>
多對多
正向查找
>>> from app01.models import News
>>> n=News.objects.get(id=1)
>>> n.favor.all()
<QuerySet [<User: User object>, <User: User object>]>
>>> n.favor.filter(name='nu1')
<QuerySet [<User: User object>]>
反向查找>>> u.news_set.all()<QuerySet [<News: News object>]>