django ORM字段和字段參數(django框架)
一、Object Relational Mapping(ORM)
1、ORM介紹
1)、ORM概念
對象關系映射(Object Relational Mapping,簡稱ORM)模式是一種為了解決面向對象與關系數據庫存在的互不匹配的現象的技術。
簡單的說,ORM是通過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關系數據庫中。
ORM在業務邏輯層和數據庫層之間充當了橋梁的作用。
2)、ORM由來
讓我們從O/R開始。字母O起源于"對象"(Object),而R則來自于"關系"(Relational)。
幾乎所有的軟件開發過程中都會涉及到對象和關系數據庫。在用戶層面和業務邏輯層面,我們是面向對象的。當對象的信息發生變化的時候,我們就需要把對象的信息保存在關系數據庫中。
按照之前的方式來進行開發就會出現程序員會在自己的業務邏輯代碼中夾雜很多SQL語句用來增加、讀取、修改、刪除相關數據,而這些代碼通常都是重復的。
3)、ORM的優勢
ORM解決的主要問題是對象和關系的映射。它通常把一個類和一個表一一對應,類的每個實例對應表中的一條記錄,類的每個屬性對應表中的每個字段。
ORM提供了對數據庫的映射,不用直接編寫SQL代碼,只需像操作對象一樣從數據庫操作數據。
讓軟件開發人員專注于業務邏輯的處理,提高了開發效率。
4)、ORM的劣勢
ORM的缺點是會在一定程度上犧牲程序的執行效率。
ORM用多了SQL語句就不會寫了,關系數據庫相關技能退化...
5)、ORM總結
ORM只是一種工具,工具確實能解決一些重復,簡單的勞動。這是不可否認的。
但我們不能指望某個工具能一勞永逸地解決所有問題,一些特殊問題還是需要特殊處理的。
但是在整個軟件開發過程中需要特殊處理的情況應該都是很少的,否則所謂的工具也就失去了它存在的意義。
2、Django中的ORM
1)、Django項目使用MySQL數據庫
1. 在Django項目的settings.py文件中,配置數據庫連接信息:
DATABASES?=?{ ????"default":?{ ????????"ENGINE":?"django.db.backends.mysql", ????????"NAME":?"你的數據庫名稱",??#?需要自己手動創建數據庫 ????????"USER":?"數據庫用戶名", ????????"PASSWORD":?"數據庫密碼", ????????"HOST":?"數據庫IP", ????????"POST":?3306 ????} }
2. 在Django項目的__init__.py文件中寫如下代碼,告訴Django使用pymysql模塊連接MySQL數據庫:
import?pymysql pymysql.install_as_MySQLdb()
2)、Model
在Django中model是你數據的單一、明確的信息來源。它包含了你存儲的數據的重要字段和行為。通常,一個模型(model)映射到一個數據庫表,
基本情況:
每個模型都是一個Python類,它是django.db.models.Model的子類。
模型的每個屬性都代表一個數據庫字段。
綜上所述,Django為您提供了一個自動生成的數據庫訪問API,詳詢官方文檔鏈接。
3、快速入門
下面這個例子定義了一個?Person?模型,包含?first_name?和?last_name。
from?django.db?import?models class?Person(models.Model): ????first_name?=?models.CharField(max_length=30) ????last_name?=?models.CharField(max_length=30)
first_name?和?last_name?是模型的字段。每個字段被指定為一個類屬性,每個屬性映射到一個數據庫列。
上面的?Person?模型將會像這樣創建一個數據庫表:
CREATE?TABLE?myapp_person?( ????"id"?serial?NOT?NULL?PRIMARY?KEY, ????"first_name"?varchar(30)?NOT?NULL, ????"last_name"?varchar(30)?NOT?NULL);
一些說明:
表myapp_person的名稱是自動生成的,如果你要自定義表名,需要在model的Meta類中指定?db_table?參數,強烈建議使用小寫表名,特別是使用MySQL作為后端數據庫時。
id字段是自動添加的,如果你想要指定自定義主鍵,只需在其中一個字段中指定?primary_key=True?即可。如果Django發現你已經明確地設置了Field.primary_key,它將不會添加自動ID列。
本示例中的CREATE TABLE SQL使用PostgreSQL語法進行格式化,但值得注意的是,Django會根據配置文件中指定的數據庫后端類型來生成相應的SQL語句。
Django支持MySQL5.5及更高版本。
二、Django ORM 常用字段和參數
1、常用字段
1)、AutoField
int自增列,必須填入參數 primary_key=True。當model中如果沒有自增列,則自動會創建一個列名為id的列。
2)、IntegerField
一個整數類型,范圍在 -2147483648 to 2147483647。
3)、CharField
字符類型,必須提供max_length參數, max_length表示字符長度。
4)、DateField
日期字段,日期格式? YYYY-MM-DD,相當于Python中的datetime.date()實例。
5)、DateTimeField
日期時間字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相當于Python中的datetime.datetime()實例。
2、字段合集(爭取記憶
字段合集:
AutoField(Field) ????????-?int自增列,必須填入參數?primary_key=True ????BigAutoField(AutoField) ????????-?bigint自增列,必須填入參數?primary_key=True ????????注:當model中如果沒有自增列,則自動會創建一個列名為id的列 ????????from?django.db?import?models ????????class?UserInfo(models.Model): ????????????#?自動創建一個列名為id的且為自增的整數列 ????????????username?=?models.CharField(max_length=32) ????????class?Group(models.Model): ????????????#?自定義自增列 ????????????nid?=?models.AutoField(primary_key=True) ????????????name?=?models.CharField(max_length=32) ????SmallIntegerField(IntegerField): ????????-?小整數?-32768?~?32767 ????PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin,?IntegerField) ????????-?正小整數?0?~?32767 ????IntegerField(Field) ????????-?整數列(有符號的)?-2147483648?~?2147483647 ????PositiveIntegerField(PositiveIntegerRelDbTypeMixin,?IntegerField) ????????-?正整數?0?~?2147483647 ????BigIntegerField(IntegerField): ????????-?長整型(有符號的)?-9223372036854775808?~?9223372036854775807 ????BooleanField(Field) ????????-?布爾值類型 ????NullBooleanField(Field): ????????-?可以為空的布爾值 ????CharField(Field) ????????-?字符類型 ????????-?必須提供max_length參數,?max_length表示字符長度 ????TextField(Field) ????????-?文本類型 ????EmailField(CharField): ????????-?字符串類型,Django?Admin以及ModelForm中提供驗證機制 ????IPAddressField(Field) ????????-?字符串類型,Django?Admin以及ModelForm中提供驗證?IPV4?機制 ????GenericIPAddressField(Field) ????????-?字符串類型,Django?Admin以及ModelForm中提供驗證?Ipv4和Ipv6 ????????-?參數: ????????????protocol,用于指定Ipv4或Ipv6,?'both',"ipv4","ipv6" ????????????unpack_ipv4,?如果指定為True,則輸入::ffff:192.0.2.1時候,可解析為192.0.2.1,開啟此功能,需要protocol="both" ????URLField(CharField) ????????-?字符串類型,Django?Admin以及ModelForm中提供驗證?URL ????SlugField(CharField) ????????-?字符串類型,Django?Admin以及ModelForm中提供驗證支持?字母、數字、下劃線、連接符(減號) ????CommaSeparatedIntegerField(CharField) ????????-?字符串類型,格式必須為逗號分割的數字 ????UUIDField(Field) ????????-?字符串類型,Django?Admin以及ModelForm中提供對UUID格式的驗證 ????FilePathField(Field) ????????-?字符串,Django?Admin以及ModelForm中提供讀取文件夾下文件的功能 ????????-?參數: ????????????????path,??????????????????????文件夾路徑 ????????????????match=None,????????????????正則匹配 ????????????????recursive=False,???????????遞歸下面的文件夾 ????????????????allow_files=True,??????????允許文件 ????????????????allow_folders=False,???????允許文件夾 ????FileField(Field) ????????-?字符串,路徑保存在數據庫,文件上傳到指定目錄 ????????-?參數: ????????????upload_to?=?""??????上傳文件的保存路徑 ????????????storage?=?None??????存儲組件,默認django.core.files.storage.FileSystemStorage ????ImageField(FileField) ????????-?字符串,路徑保存在數據庫,文件上傳到指定目錄 ????????-?參數: ????????????upload_to?=?""??????上傳文件的保存路徑 ????????????storage?=?None??????存儲組件,默認django.core.files.storage.FileSystemStorage ????????????width_field=None,???上傳圖片的高度保存的數據庫字段名(字符串) ????????????height_field=None???上傳圖片的寬度保存的數據庫字段名(字符串) ????DateTimeField(DateField) ????????-?日期+時間格式?YYYY-MM-DD?HH:MM[:ss[.uuuuuu]][TZ] ????DateField(DateTimeCheckMixin,?Field) ????????-?日期格式??????YYYY-MM-DD ????TimeField(DateTimeCheckMixin,?Field) ????????-?時間格式??????HH:MM[:ss[.uuuuuu]] ????DurationField(Field) ????????-?長整數,時間間隔,數據庫中按照bigint存儲,ORM中獲取的值為datetime.timedelta類型 ????FloatField(Field) ????????-?浮點型 ????DecimalField(Field) ????????-?10進制小數 ????????-?參數: ????????????max_digits,小數總長度 ????????????decimal_places,小數位長度 ????BinaryField(Field) ????????-?二進制類型
3、自定義字段(了解為主)
class?UnsignedIntegerField(models.IntegerField): ????def?db_type(self,?connection): ????????????return?'integer?UNSIGNED'
自定義char類型字段:
class?FixedCharField(models.Field): ????""" ????自定義的char類型的字段類 ????""" ????def?__init__(self,?max_length,?*args,?**kwargs): ????????super().__init__(max_length=max_length,?*args,?**kwargs) ????????self.length?=?max_length ????def?db_type(self,?connection): ????????""" ????????限定生成數據庫表的字段類型為char,長度為length指定的值 ????????""" ????????return?'char(%s)'?%?self.length class?Class(models.Model): ????id?=?models.AutoField(primary_key=True) ????title?=?models.CharField(max_length=25) ????#?使用上面自定義的char類型的字段 ????cname?=?FixedCharField(max_length=25)
創建的表結構:
附ORM字段與數據庫實際字段的對應關系
對應關系:
對應關系: ????'AutoField':?'integer?AUTO_INCREMENT', ????'BigAutoField':?'bigint?AUTO_INCREMENT', ????'BinaryField':?'longblob', ????'BooleanField':?'bool', ????'CharField':?'varchar(%(max_length)s)', ????'CommaSeparatedIntegerField':?'varchar(%(max_length)s)', ????'DateField':?'date', ????'DateTimeField':?'datetime', ????'DecimalField':?'numeric(%(max_digits)s,?%(decimal_places)s)', ????'DurationField':?'bigint', ????'FileField':?'varchar(%(max_length)s)', ????'FilePathField':?'varchar(%(max_length)s)', ????'FloatField':?'double?precision', ????'IntegerField':?'integer', ????'BigIntegerField':?'bigint', ????'IPAddressField':?'char(15)', ????'GenericIPAddressField':?'char(39)', ????'NullBooleanField':?'bool', ????'OneToOneField':?'integer', ????'PositiveIntegerField':?'integer?UNSIGNED', ????'PositiveSmallIntegerField':?'smallint?UNSIGNED', ????'SlugField':?'varchar(%(max_length)s)', ????'SmallIntegerField':?'smallint', ????'TextField':?'longtext', ????'TimeField':?'time', ????'UUIDField':?'char(32)',
4、字段參數
1)、null
用于表示某個字段可以為空。
2)、unique
如果設置為unique=True 則該字段在此表中必須是唯一的 。
3)、db_index
如果db_index=True 則代表著為此字段設置數據庫索引。
4)、default
為該字段設置默認值。
5、時間字段獨有
DatetimeField、DateField、TimeField這個三個時間字段,都可以設置如下屬性。
1)、auto_now_add
配置auto_now_add=True,創建數據記錄的時候會把當前時間添加到數據庫。
2)、auto_now
配置上auto_now=True,每次更新數據記錄的時候會更新該字段。
三、關系字段
四、ForeignKey
外鍵類型在ORM中用來表示外鍵關聯關系,一般把ForeignKey字段設置在 '一對多'中'多'的一方。
ForeignKey可以和其他表做關聯關系同時也可以和自身做關聯關系。
1、字段參數
1)、to
設置要關聯的表
2)、to_field
設置要關聯的表的字段
3)、related_name
反向操作時,使用的字段名,用于代替原反向查詢時的'表名_set'。
例如:
class?Classes(models.Model): ????name?=?models.CharField(max_length=32) class?Student(models.Model): ????name?=?models.CharField(max_length=32) ????theclass?=?models.ForeignKey(to="Classes")
當我們要查詢某個班級關聯的所有學生(反向查詢)時,我們會這么寫:
models.Classes.objects.first().student_set.all()
當我們在ForeignKey字段中添加了參數?related_name?后,
class?Student(models.Model): ????name?=?models.CharField(max_length=32) ????theclass?=?models.ForeignKey(to="Classes",?related_name="students")
當我們要查詢某個班級關聯的所有學生(反向查詢)時,我們會這么寫:
models.Classes.objects.first().students.all()
4)、related_query_name
反向查詢操作時,使用的連接前綴,用于替換表名。
5)、on_delete
當刪除關聯表中的數據時,當前表與其關聯的行的行為。
models.CASCADE
刪除關聯數據,與之關聯也刪除
models.DO_NOTHING
刪除關聯數據,引發錯誤IntegrityError
models.PROTECT
刪除關聯數據,引發錯誤ProtectedError
models.SET_NULL
刪除關聯數據,與之關聯的值設置為null(前提FK字段需要設置為可空)
models.SET_DEFAULT
刪除關聯數據,與之關聯的值設置為默認值(前提FK字段需要設置默認值)
models.SET
刪除關聯數據,
a. 與之關聯的值設置為指定值,設置:models.SET(值)
b. 與之關聯的值設置為可執行對象的返回值,設置:models.SET(可執行對象)
def?func(): ????return?10 class?MyModel(models.Model): ????user?=?models.ForeignKey( ????????to="User", ????????to_field="id", ????????on_delete=models.SET(func) ????)
6)、db_constraint
是否在數據庫中創建外鍵約束,默認為True。
五、OneToOneField
一對一字段。
通常一對一字段用來擴展已有字段。
1、示例
一對一的關聯關系多用在當一張表的不同字段查詢頻次差距過大的情況下,將本可以存儲在一張表的字段拆開放置在兩張表中,然后將兩張表建立一對一的關聯關系。
class?Author(models.Model): ????name?=?models.CharField(max_length=32) ????info?=?models.OneToOneField(to='AuthorInfo')???? class?AuthorInfo(models.Model): ????phone?=?models.CharField(max_length=11) ????email?=?models.EmailField()
2、字段參數
1)、to
設置要關聯的表。
2)、to_field
設置要關聯的字段。
3)、on_delete
同ForeignKey字段。
六、ManyToManyField
用于表示多對多的關聯關系。在數據庫中通過第三張表來建立關聯關系。
1、字段參數
1)、to
設置要關聯的表
2)、related_name
同ForeignKey字段。
3)、related_query_name
同ForeignKey字段。
4)、symmetrical
僅用于多對多自關聯時,指定內部是否創建反向操作的字段。默認為True。
舉個例子:
class?Person(models.Model): ????name?=?models.CharField(max_length=16) ????friends?=?models.ManyToManyField("self")
此時,person對象就沒有person_set屬性。
class?Person(models.Model): ????name?=?models.CharField(max_length=16) ????friends?=?models.ManyToManyField("self",?symmetrical=False)
此時,person對象現在就可以使用person_set屬性進行反向查詢。
5)、through
在使用ManyToManyField字段時,Django將自動生成一張表來管理多對多的關聯關系。
但我們也可以手動創建第三張表來管理多對多關系,此時就需要通過through來指定第三張表的表名。
6)、through_fields
設置關聯的字段。
7)、db_table
默認創建第三張表時,數據庫中表的名稱。
2、多對多關聯關系的三種方式
1)、方式一:自行創建第三張表
2)、方式二:通過ManyToManyField自動創建第三張表
3)、方式三:設置ManyTomanyField并指定自行創建的第三張表
注意:
當我們需要在第三張關系表中存儲額外的字段時,就要使用第三種方式。
但是當我們使用第三種方式創建多對多關聯關系時,就無法使用set、add、remove、clear方法來管理多對多的關系了,需要通過第三張表的model來管理多對多關系。
3、元信息
ORM對應的類里面包含另一個Meta類,而Meta類封裝了一些數據庫的信息。主要字段如下:
1)、db_table
ORM在數據庫中的表名默認是?app_類名,可以通過db_table可以重寫表名。
2)、index_together
聯合索引。
3)、unique_together
聯合唯一索引。
4)、ordering
指定默認按什么字段排序。
只有設置了該屬性,我們查詢到的結果才可以被reverse()。
軟件開發 人工智能 云計算 機器學習
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。