對象關係映射(Object Relational Mapping,簡稱 ORM)模式是一種爲了解決面向對象與關係數據庫存在的互不匹配的現象的技術。簡單的說,ORM 是經過使用描述對象和數據庫之間映射的元數據,將程序中的對象自動持久化到關係數據庫中,它實現了數據模型與數據庫的解耦,即數據模型的設計不須要依賴於特定的數據庫,經過簡單的配置就能夠輕鬆更換數據庫,這極大的減輕了開發人員的工做量,不須要面對因數據庫變動而致使的無效勞動。python
sql中的表 CREATE TABLE employee( id INT PRIMARY KEY auto_increment , name VARCHAR (20), gender BIT default 1, birthday DATA , department VARCHAR (20), salary DECIMAL (8,2) unsigned, ); 添加一條表紀錄: INSERT employee(name, gender, birthday, salary, department) VALUES("alex", 1, "1985-12-12", 8000, "保潔部"); 查詢一條表紀錄: SELECT * FROM employee WHERE age=24; 更新一條表紀錄: UPDATE employee SET birthday="1989-10-24" WHERE id=1; 刪除一條表紀錄: DELETE FROM employee WHERE name="alex"
# python的類 class Employee(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) gender = models.BooleanField() birthday = models.DateField() department = models.CharField(max_length=32) salary = models.DecimalField(max_digits=8,decimal_places=2) # 添加一條表紀錄: emp=Employee(name="alex",gender=True,birthday="1985-12-12",epartment="保潔部") emp.save() # 查詢一條表紀錄: Employee.objects.filter(age=24) # 更新一條表紀錄: Employee.objects.filter(id=1).update(birthday="1989-10-24") # 刪除一條表紀錄: Employee.objects.filter(name="alex").delete()
類 —— 表 類屬性 —— 表字段 類對象 —— 表記錄
建立名爲 app01 的 app,在 app01 下的 models.py 中建立模型mysql
class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=20) price = models.DecimalField(max_digits=5, decimal_places=2) pub_data = models.DateTimeField() publish = models.CharField(max_length=32)
每一個字段有一些特有的參數,例如,CharField 須要 max_length 參數來指定數據庫字段的大小。還有一些適用於全部字段的通用參數。 這些參數在文檔中有詳細定義,這裏只簡單介紹一些最經常使用的:git
AutoField - int自增列,必須填入參數 primary_key=True BooleanField - 布爾值類型 CharField - 字符類型,必須提供 max_length 參數,max_length表示字符長度 TextField - 文本類型 EmailField - Django Admin 以及 ModelForm 中提供驗證機制 ImageField - 字符串,路徑保存在數據庫,文件上傳到指定目錄 - 參數: upload_to = "" 上傳文件的保存路徑 storage = None 存儲組件,默認django.core.files.storage.FileSystemStorage width_field=None 上傳圖片的高度保存的數據庫字段名(字符串) height_field=None 上傳圖片的寬度保存的數據庫字段名(字符串) DateTimeField - 日期+時間格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField - 日期格式 YYYY-MM-DD TimeField - 時間格式 HH:MM[:ss[.uuuuuu]] FloatField - 浮點型 DecimalField - 10進制小數 - 參數: max_digits 小數總長度 decimal_places 小數位長度
一、null 若是爲True,Django 將用NULL 來在數據庫中存儲空值。 默認值是 False. 二、blank 若是爲True,該字段容許不填。默認爲False。 要注意,這與 null 不一樣。null純粹是數據庫範疇的,而 blank 是數據驗證範疇的。 若是一個字段的blank=True,表單的驗證將容許該字段是空值。若是字段的blank=False,該字段就是必填的。 三、default 字段的默認值。能夠是一個值或者可調用對象。若是可調用 ,每有新對象被建立它都會被調用。 四、primary_key 若是爲True,那麼這個字段就是模型的主鍵。若是沒有指定任何一個字段的 primary_key=True, Django就會自動添加一個 IntegerField 字段作爲主鍵, 因此除非想覆蓋默認的主鍵行爲,不然不必設置任何一個字段的primary_key=True。 五、unique 若是該值設置爲 True, 這個數據字段的值在整張表中必須是惟一的 六、choices 由二元組組成的一個可迭代對象(例如,列表或元組),用來給字段提供選擇項。 若是設置了choices ,默認的表單將是一個選擇框而不是標準的文本框,並且這個選擇框的選項就是choices中的選項。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'bms', # 要鏈接的數據庫,鏈接前須要建立好 'USER': 'root', # 鏈接數據庫的用戶名 'PASSWORD': '000000', # 鏈接數據庫的密碼 'HOST': '127.0.0.1', # 鏈接主機,默認本級 'PORT': 3306, # 端口 默認3306 } }
注意一:NAME 即數據庫的名字,在 mysql 鏈接前該數據庫必須已經建立,而上面的 sqlite 數據庫下的 db.sqlite3 則是項目自動建立。 USER 和 PASSWORD 分別是數據庫的用戶名和密碼。設置完後,在啓動 Django 項目前,須要激活 mysql。而後啓動項目,會報錯:no module named MySQLdb 。這是由於 django 默認導入的驅動是 MySQLdb,但是 MySQLdb 對於 Python3 有很大問題,所以使用驅動 PyMySQL。因此,須要找到項目名文件下的 __init__.py
,在裏面寫入:sql
import pymysql pymysql.install_as_MySQLdb()
注意二:確保配置文件中的 INSTALLED_APPS 中寫入了建立的 app 名稱數據庫
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', ]
django 會把 settings 中的 INSTALLED_APPS 的每個應用中 models 對應的類建立成數據庫中的表,在當前環境的項目目錄下執行兩個命令:django
python manage.py makemigrations python manage.py migrate
# create方法的返回值book_obj就是插入Book表中的這本書的記錄對象 book_obj = Book.objects.create(title="圖解HTTP", price=49, pub_date="2014-11-12", publish="人民郵電出版社")
book_obj = Book(title="圖解HTTP", price=49, pub_date="2014-11-12", publish="人民郵電出版社") book_obj.save()
爲了方便查詢,在此以前已添加多條記錄api
all() 查詢全部結果 filter(**kwargs) 它包含了與所給篩選條件相匹配的對象 get(**kwargs) 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。 exclude(**kwargs) 它包含了與所給篩選條件不匹配的對象 order_by(*field) 對查詢結果排序 reverse() 對查詢結果反向排序 count() 返回數據庫中匹配查詢(QuerySet)的對象數量。 first() 返回第一條記錄 last() 返回最後一條記錄 exists() 若是QuerySet包含數據,就返回True,不然返回False values(*field) 返回一個ValueQuerySet,一個特殊的QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列 values_list(*field) 它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列 distinct() 從返回結果中剔除重複紀錄
def addbook(request): # 添加表記錄 # book = Book.objects.create(title="圖解HTTP", price=49, pub_date="2014-11-12", publish="人民郵電出版社") # 查詢表記錄 # 一、all:返回一個QuerySet對象 # book_list = Book.objects.all() # print(book_list[0].title) # 圖解HTTP # print(book_list) # <QuerySet [<Book: Book object>]> # 查詢全部書籍名 # for obj in book_list: # print(obj.title) # 二、first/last:調用者是QuerySet對象,返回值是對象 # book = Book.objects.all().first() # book_2 = Book.objects.all().last() # print(book) # print(book2) # 三、filter:返回值是QuerySet對象(至關於where語句),能夠加多個過濾條件 # book = Book.objects.filter(title='圖解TCP/IP').first() # print(book) # 四、get:有且只有一個查詢結果纔有意義,返回值是一個對象 # 沒有這個查詢結果會報錯 # book = Book.objects.get(title='Python源碼剖析') # print(book) # 五、exclude:除了查詢以外的,返回值也是QuerySet # ret = Book.objects.exclude(title='圖解HTTP') # print(ret) # 六、order_by:默認升序,加個-就是降序。能夠有多個過濾條件,調用者是QuerySet,返回值也是QuerySet # book_list = Book.objects.all().order_by('nid') # book_list_2 = Book.objects.all().order_by('-id', 'price') # print(book_list) # 七、count:調用者是QuerySet,返回值是int # ret = Book.objects.all().count() # print(ret) # 八、exists:判斷是是否有值,不能傳參數 # ret = Book.objects.all().exists() # print(ret) # 九、values:調用是QuerySet,返回值也是QuerySet # ret = Book.objects.values('price') # print(ret) # 十、value_list:調用是QuerySet,返回值也是QuerySet # ret = Book.objects.all().values_list('price', 'title') # print(ret) # 十一、distinct:調用是QuerySet,返回值也是QuerySet # ret = Book.objects.all().values('title').distinct() # print(ret) return HttpResponse('OK')
# 查詢價格大於50的書的名字 # ret = Book.objects.filter(price__gt=50).values('title') # print(ret) # 查詢大於40小於50的書 # ret = Book.objects.filter(price__gt=40, price__lt=50) # print(ret) # 查詢以「圖解」開頭的書的名字 # ret = Book.objects.filter(title__startswith='圖解').values('title') # print(ret) # 查詢包含‘Python’的書 # ret = Book.objects.filter(title__contains='Python').values('title') # print(ret) # icontains 不區分大小寫 # 價格在69,89,100中的 # ret = Book.objects.filter(price__in=[69, 89, 100]).values('title') # print(ret) # 出版日期在2016年的 # ret = Book.objects.filter(pub_date__year=2016) # print(ret)
刪除方法就是 delete,它運行時當即刪除對象而不返回任何值。例如:session
model_obj.delete()
也能夠一次性刪除多個對象。每一個 QuerySet 都有一個 delete() 方法,它一次性刪除 QuerySet 中全部的對象。例如,下面的代碼將刪除 pub_date 是 2005 年的 Entry 對象:app
Entry.objects.filter(pub_date__year=2005).delete()
在 Django 刪除對象時,會模仿 SQL 約束 ON DELETE CASCADE 的行爲,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。例如:設計
b = Blog.objects.get(pk=1) # This will delete the Blog and all of its Entry objects. b.delete()
要注意的是: delete() 方法是 QuerySet 上的方法,但並不適用於 Manager 自己。這是一種保護機制,是爲了不意外地調用 Entry.objects.delete() 方法致使全部的記錄被誤刪除。若是確認要刪除全部的對象,那麼必須顯式地調用:
Entry.objects.all().delete()
若是不想級聯刪除,能夠設置爲:
pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)
Book.objects.filter(title__startswith="Py").update(price=120)
此外,update 方法對於任何結果集(QuerySet)均有效,這意味着能夠同時更新多條記錄 update 方法會返回一個整型數值,表示受影響的記錄條數。
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled15.settings") import django django.setup() from app01 import models books = models.Book.objects.all() print(books)
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }