對象關係映射(Object Relational Mapping,簡稱ORM)模式是一種爲了解決面向對象與關係數據庫存在的互不匹配的現象的技術。mysql
簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係數據庫中。程序員
ORM在業務邏輯層和數據庫層之間充當了橋樑的做用。sql
讓咱們從O/R開始。字母O起源於"對象"(Object),而R則來自於"關係"(Relational)。數據庫
幾乎全部的軟件開發過程當中都會涉及到對象和關係數據庫。在用戶層面和業務邏輯層面,咱們是面向對象的。當對象的信息發生變化的時候,咱們就須要把對象的信息保存在關係數據庫中。django
按照以前的方式來進行開發就會出現程序員會在本身的業務邏輯代碼中夾雜不少SQL語句用來增長、讀取、修改、刪除相關數據,而這些代碼一般都是重複的。後端
ORM解決的主要問題是對象和關係的映射。它一般把一個類和一個表一一對應,類的每一個實例對應表中的一條記錄,類的每一個屬性對應表中的每一個字段。 app
ORM提供了對數據庫的映射,不用直接編寫SQL代碼,只需像操做對象同樣從數據庫操做數據。ide
讓軟件開發人員專一於業務邏輯的處理,提升了開發效率。工具
ORM的缺點是會在必定程度上犧牲程序的執行效率。spa
ORM用多了SQL語句就不會寫了,關係數據庫相關技能退化...
ORM只是一種工具,工具確實能解決一些重複,簡單的勞動。這是不能否認的。
但咱們不能期望某個工具能一勞永逸地解決全部問題,一些特殊問題仍是須要特殊處理的。
可是在整個軟件開發過程當中須要特殊處理的狀況應該都是不多的,不然所謂的工具也就失去了它存在的意義。
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()
在Django中model是你數據的單1、明確的信息來源。它包含了你存儲的數據的重要字段和行爲。一般,一個模型(model)映射到一個數據庫表,
基本狀況:
下面這個例子定義了一個 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 );
一些說明:
int自增列,必須填入參數 primary_key=True。當model中若是沒有自增列,則自動會建立一個列名爲id的列。
一個整數類型,範圍在 -2147483648 to 2147483647。
字符類型,必須提供max_length參數, max_length表示字符長度。
日期字段,日期格式 YYYY-MM-DD,至關於Python中的datetime.date()實例。 ##這個只有年月日
日期時間字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],至關於Python中的datetime.datetime()實例。 ##這個是帶時間的 須要有auto_now_add=TRue 須要或者參數,在添加數據的時候,這個值把當前的時候存進去
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): self.max_length = max_length super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection): """ 限定生成數據庫表的字段類型爲char,長度爲max_length指定的值 """ return 'char(%s)' % self.max_length class Class(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=25) # 使用自定義的char類型的字段 cname = FixedCharField(max_length=25)
建立的表結構:
附ORM字段與數據庫實際字段的對應關係
用於表示某個字段能夠爲空。
若是設置爲unique=True 則該字段在此表中必須是惟一的 。
若是db_index=True 則表明着爲此字段設置索引。
爲該字段設置默認值。
配置auto_now_add=True,建立數據記錄的時候會把當前時間添加到數據庫。
配置上auto_now=True,每次更新數據記錄的時候會更新該字段。
外鍵類型在ORM中用來表示外鍵關聯關係,通常把ForeignKey字段設置在 '一對多'中'多'的一方。
ForeignKey能夠和其餘表作關聯關係同時也能夠和自身作關聯關係。
設置要關聯的表
設置要關聯的表的字段
反向操做時,使用的字段名,用於代替原反向查詢時的'表名_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()
反向查詢操做時,使用的鏈接前綴,用於替換表名。
當刪除關聯表中的數據時,當前表與其關聯的行的行爲。
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) )
是否在數據庫中建立外鍵約束,默認爲True。
一對一字段。
一般一對一字段用來擴展已有字段。
設置要關聯的表。
設置要關聯的字段。
同ForeignKey字段。
用於表示多對多的關聯關係。在數據庫中經過第三張表來創建關聯關係。
##第三張表的好處是能夠爲之後增長一些信息更方便。
##第三張表須要指定外鍵這樣才能夠
## 第三張表的字段名字不能加id
設置要關聯的表
同ForeignKey字段。
同ForeignKey字段。
僅用於多對多自關聯時,指定內部是否建立反向操做的字段。默認爲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屬性進行反向查詢。
在使用ManyToManyField字段時,Django將自動生成一張表來管理多對多的關聯關係。
但咱們也能夠手動建立第三張表來管理多對多關係,此時就須要經過through來指定第三張表的表名。
設置關聯的字段。 ##這個是在手動建立第三張表,有了Book2Author這個類之後才使用這個參數。
class Book(models.Model): title = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) # books = models.ManyToManyField( to="Book", through="Book2Author", through_fields=('author', 'book') ) # 本身建立第三張表 class Book2Author(models.Model): id = models.AutoField(primary_key=True) book = models.ForeignKey(to=Book) author = models.ForeignKey(to=Author) first_blood = models.DateField()
默認建立第三張表時,數據庫中表的名稱。
ORM對應的類裏面包含另外一個Meta類,而Meta類封裝了一些數據庫的信息。主要字段以下:
ORM在數據庫中的表名默認是 app_類名,能夠經過db_table能夠重寫表名。
聯合索引。
聯合惟一索引。
指定默認按什麼字段排序。
只有設置了該屬性,咱們查詢到的結果才能夠被reverse()。