Django Web应用开发实战第七章
生活随笔
收集整理的這篇文章主要介紹了
Django Web应用开发实战第七章
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、ORM框架
Django對各種數據庫提供了很好的支持,包括PostgreSQL、MySQL、SQLite和Oracle,且為這些數據庫提供了統一API方法,這些API統稱為ORM框架。
通過Django內置的ORM框架可以實現數據庫連接和讀寫操作。
二、模型定義與數據遷移
ORM框架是一種程序技術,用于實現 面向對象編程語言中不同類型系統的數據之間的轉換,從效果上說,它創建了一個可在編程語言中使用的“虛擬對象數據庫”,通過對虛擬對象數據庫的操作,實現對目標數據庫的操作,虛擬對象數據庫與目標數據庫是相互對應的。在Django中虛擬對象數據庫也稱為模型。模型字段如下:
- AutoField: 自增長類型,數據表的字段類型為整數,長度為11位
- BigAutoField: 自增長類型,數據表的字段類型為bigint,長度為20位
- CharField: 字符類型
- BooleanField: 布爾類型
- CommonSeparateIntegerField: 用逗號分割的整數類型
- DateField: 日期(Date)類型
- DatetimeField: 日期時間(Datetime)類型
- Decimal: 十進制小數類型
- EmailField: 字符類型,存儲郵箱格式的字符串
- FloatField: 浮點數類型,數據表的字段類型變成Double類型
- IntegerField: 整數類型,數據表的字段類型為11位的整數
- BigIntegerField: 長整數類型
- IPAddressField: 字符類型,存儲Ipv4地址的字符串
- GenericIPAddressField: 字符類型,存儲Ipv4和Ipv6地址的字符串
- NullBooleanField: 允許為空的布爾類型
- PositiveIntegerField: 正整數的整數類型
- PositiveSmallIntegerField: 小正整數類型,取值范圍0~32767
- SlugField: 字符類型,包含字母、數字、下劃線和連字符的字符串
- TextField: 長文本類型
- TimeField: 時間類型,顯示時分秒HH:MM[:ss[.uuuuuuu]]
- URLField: 字符類型,存儲路由格式的字符串
- BinaryField: 二進制數據類型
- FileField: 字符類型,存儲文件路徑的字符串
- ImageField: 字符類型,存儲圖片路徑的字符串
- FilePathField: 字符類型,從特定的文件目錄選擇某個文件
允許設置的參數
源碼Field(django/db/models/fields/init.py)
- verbose_name: 默認None,在Admin站點管理設置字符的顯示名稱
- primary_key: 默認為False,若為True,則將字段設置成主鍵
- max_length: 默認為None,設置字段的最大長度
- unique: 默認為False,若為True,則設置字段的唯一屬性
- blank: 默認為False, 若為True,則設置字段允許為空值,數據庫將存儲空字符串
- null: 默認為False,若為True,則字段允許為空值,數據庫表現為NULL
- db_index: 默認為False,若為True,則以此字段來創建數據庫索引
- default: 默認為NOT_PROVIDEDD對象,設置字段的默認值
- editable: 默認為True,允許字段可編輯,用于設置Admin的新增數據的字段
- serialize: 默認為True,允許字段序列化,可將數據轉化為JSON格式
- unique_for_date: 默認為None,設置日期字段的唯一性
- unique_for_month: 默認為None,設置月份字段的唯一性
- unique_for_year: 默認為None,設置年份字段的唯一性
- choices: 默認空列表,設置字段的可選值
- help_text: 默認為空字符串,用于設置表單的提示信息
- db_column: 默認為None,設置數據表的列名稱,若不設置,則字段名作為列名
- db_tablespace: 默認為None,如果字段已創建索引,那么數據庫的表空間名稱將作為該字段的索引名稱。注意:部分數據庫不支持表空間
- auto_created: 默認為False,若為True,則自動創建字段,用于一對一的關系模型
- validators: 默認為空列表,設置字段內容的驗證函數
- error_message: 默認為None,設置錯誤提示
- 以上參數適用于所有字段
- 以下適用于Meta
- abstract: 若設置為True,則該模型為抽象模型,不會在數據庫里創建數據表
- app_label:屬性值為字符串,將模型設置為指定的項目應用,比如將index的models.py定義的模型A指定到其他的APP里
- db_table: 屬性值為字符串,設置模型所使用的數據庫的表名
- db_tablespace: 屬性值為字符串,設置模型所使用的數據庫的表名
- get_lastest_by: 屬性值為字符串或列表,設置模型數據的排序方式
- managed: 默認為True,支持Django命令執行數據遷移;若為False,則不支持數據遷移功能
- order_with_respect_to: 屬性值為字符串,用于多對多的模型關系,指向某個關系模型的名稱,并且模型名稱必須為英文小寫。若A模型對B模型一對多,兩個模型關聯后,當查詢模型A的某條數據時,可使用get_b_order()和set_b_order()來獲取B的關聯數據;可使用get_next_in_order()和get_previous_in_order()獲取當前數據的上一條和下一條數據
- ordering: 屬性值為列表,將模型數據以某個字段進行排序
- permissions: 屬性值為元組,設置模型的訪問權限,默認設置添加、修改和刪除的權限
- proxy:若設置為True,則為模型創建代理模型,即為模塊A克隆一個相同的模型B
- required_db_features:屬性值為列表,聲明模型依賴的數據庫功能,如['gis_enabled'],表示模型依賴GIS功能
- required_db_vendor: 屬性值為列表,聲明模型依賴的數據庫,默認支持SQLite、PostgreSQL、MySQL和Oracle
- select_on_save: 數據新增修改算法,通常無需設置,默認為False
- indexes: 屬性值為列表,定義數據庫表的索引列表
- verbos_name: 屬性值為字符串,設置模型直觀可讀的名稱并以復數形式表示
- verbos_name_plural: 與verbos_name相同,以單數形式表示
- label: 只讀屬性,屬性值為app_label.object_name
- label_lower: 與label相同,但其值為字母小寫
導數據
# 導出項目所有數據表
python manage.py dumpdata > data.json # 導出某個項目名稱所有模型
python manage.py dumpdata index > data.json # 導出某個項目某個模型名稱
python manage.py dumpdata index.PersonInfo > data.json # 導入數據
python manage.py loaddata data.json
三、數據表關系
# OneToOneField、ForeignKey、ManyToManyField
# 參數
- to: 必選參數,關聯的模型名稱
- on_delete: 必選參數,設置數據刪除模式,刪除模型包括:CASCADE/PROTECT/SET_NULL/SET_DEFAULT/SET/DO_NOTHING
- limit_choices_to: 設置外鍵的下拉選項,用于模型與表單和Admin后臺系統
- related_name: 用于模型之間的關聯查詢,如反向查詢
- related_query_name: 設置模型的查詢名稱,用于filter或get查詢,若設置參數related_name則以該參數為默認值,若沒有設置,則以模型名稱的小寫為默認值
- to_field: 設置外鍵與其他模型字段的關聯性,默認關聯主鍵,若要關聯其他字段,則該字段必須具有唯一性
- db_constraint: 在數據庫里是否創建外鍵約束,默認為true
- swappable: 設置關聯模型的替換功能,默認為true,比如模型A關聯模型B,想讓模型C繼承并替換B使得A與模型C之間關聯
- symmetrical: 僅限于ManyToManyField,設置多對多字段之間的對稱模式
- through: 僅限于ManyToManyField,設置自定義模型C,用于管理和創建模型A和B否多對多關系
- through_fields: 僅限于ManyToManyField,設置模型C的字段,確認模型C的哪些字段用于管理A和B否多對多關系
- db_table: 僅限于ManyToManyField,為管理和存儲多對多關系的數據表設置表名稱
四、數據查詢
去重distinct
# 去重查詢,distinct無需設置參數,去重方式根據values設置的字段執行
# SQL: select * from index_vocation where job='123';
v = Vocation.objects.values('job').filter(job='123').distinct()
聚合查詢annotate、aggregate
# annotate類似sql里面的group by
# 如果不設置values,默認對主鍵進行group by分組
# SQL: select job, sum(id) as 'id__sum' from index_vocation group by job;
v = Vocation.objects.annotate(Sum('id')) # aggregate是計算某個字段的值并返回計算結果
# SQL: select count(id) as 'id__count' from index_vocation
v = Vocation.objects.aggregate(id_count=Count('id'))
結果集union、intersection、difference
# 每次查詢的字段必須一致
v1 = Vocation.objects.filter(payment__gt=9000)
v2 = Vocation.objects.filter(payment__gt=5000) # 使用SQL UNION來組合兩個或多個查詢結果的并集
v1.union(v2) # 使用SQL INTERSECT來獲取兩個或多個查詢結果的交集
v1.intersection(v2) # 使用SQL EXCEPT來獲取兩個或多個查詢結果的差集
v2.difference(v2)
查詢條件get:查詢字段必須是主鍵或者唯一約束的字段,且查詢的數據必須存在,否則程序會拋異常
查詢條件filter:查詢字段沒有限制,只要該字段是數據表某一字即可。查詢結果以列表形式返回,查詢結果為空就返回空列表
多表查詢select_related、prefetch_related
# select_related參數為字符串格式(外鍵字段related_name), 使用left outer join方式查詢兩個數據表
# 查詢模型PersonInfo的name字段和模型Vocation的payment字段
p = PersonInfo.objects.select_related('personinfo').values('name', 'personinfo__payment') # select_related使用SQL的join實現的,對于多對多會增加數據查詢時間和內存占用;prefetch_related更有優勢
# 查詢模型Program的某行數據
p = Program.objects.prefetch_related('performer').filter(name='123').first()
# 根據外鍵字段proformer獲取當前數據的多對多或一對多關系
p.performer.all()
執行sql
# extra: 結果集修改器,一種提供額外查詢參數的機制
# 查詢job=123的數據
v = Vocation.objects.extra(where=['job=%s'], params=['123']) # 新增查詢字段seat, select_params為selec的%s提供參數
v = Vocation.objects.extra(select={'seat': '%s'}, select_params=['seatInfo']) # raw
v = Vocation.objects.raw('select * from index_vocation')
v[0] # execute很容易受到sql注入攻擊
from django.db import connection
cursor = connection.cursor()
cursor.execute('select * from index_vocation')
# 讀取第一行數據
cursor.fetchone()
# 讀取所有數據
cursor.fetchall()
遷移到不同數據庫
# 在default數據庫中創建數據表
python manage.py migrate # 在db1中創建數據表
python manage.py migrate --database=db1
五、數據庫事務
事物是指作為單個邏輯執行的一系列操作,這些操作具有原子性,即這些操作要么完全執行,要么完全不執行。
事物處理可以確保事務性單元內所有操作都成功完成,否則不會執行數據操作。
事物四大特性ACID:
- 原子性(Atomicity):一個事物是一個不可分割的工作單位,事物中包括的操作要么都做,要么都不做。
- 一致性(Consistency):事物必須使數據庫從某個一致性狀態到另一個一致性狀態,一致性與原子性是密切相關的。
- 隔離性:一個事物的執行不能被其他事物干擾,即一個事物內部的操作及使用的數據對其他事物是隔離的,各個事物之間互不干擾。
- 持久性:也稱永久性(Permanence),指一個事物一旦提交,它對數據庫中數據的改變應該是永久性的,其他操作或故障不應該對其有任何影響。 # Django事物定義在django/db/transaction.py
- atomic(): 在視圖函數或視圖類使用事物
- savepoint(): 開啟事物
- savepoint_rollback(): 回滾事物
- savepoint_save(): 提交事物
from django.shortcuts import render
from .models import *
from django.db import transaction
from django.db.models import F @transaction.atomic
def index(request):
# 開啟事物保護
sid = transaction.savepoint()
try:
id = request.GET.get('id', '')
if id:
v = Vocation.objects.filter(id=id)
v.update(payment=F('payment') + 1)
print('Done')
# 提交事物
# 如不設置,當程序執行完成后,會自動提交事物
# transaction.savepoint_commit(sid)
else:
# 全表的payment字段自減1
Vocation.objects.update(payment=F('payment') - 1)
# 事物回滾,將全表payment字段自減1的操作撤回
transaction.savepoint_rollback(sid)
except Expection as e:
transaction.savepoint_rollback(sid) return render(request, 'index.html', local()) # 使用with模塊實現
with transaction.atmonic():
pass
六、發送郵件
# 郵件配置信息
EMAIL_USE_SSL = True # Django與郵件服務器的連接方式是否設置ssl模式 # 郵件服務器,如果是163,就改成smtp.163.com
EMAIL_HOST = 'smtp.qq.com' # 設置服務器類型,qq郵箱分為SMTP和POP3服務器 # 郵件服務器端口
EMAIL_PORT = 465 # 若使用SMTP服務器,則端口應為465或587 # 發送郵件的賬號
EMAIL_HOST_USER = '4512125@qq.com' # 賬號必須開啟POP3/SMTP服務 # SMTP服務密碼
EMAIL_HOST_PASSWORD = 'SFSDDSFSVGSF' # 授權碼 # 設置默認發送郵件的賬號
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
總結
以上是生活随笔為你收集整理的Django Web应用开发实战第七章的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 9天的小奶猫眼睛一大一小,是否有先天发育
- 下一篇: 学人工智能感觉怎么样