模型準(zhǔn)確且唯一的描述了數(shù)據(jù)。它包含您儲存的數(shù)據(jù)的重要字段和行為。一般來說,每一個模型都映射一張數(shù)據(jù)庫表。
- 每個模型都是一個 Python 的類,這些類繼承 django.db.models.Model
- 模型類的每個屬性都相當(dāng)于一個數(shù)據(jù)庫的字段。
- 利用這些,Django 提供了一個自動生成訪問數(shù)據(jù)庫的 API;
字段類型
模型中每一個字段都應(yīng)該是某個 Field 類的實例, Django 利用這些字段類來實現(xiàn)以下功能:
- 字段類型用以指定數(shù)據(jù)庫數(shù)據(jù)類型(如:INTEGER, VARCHAR, TEXT)。
- 在渲染表單字段時默認(rèn)使用的 HTML 視圖 (如: , )。
- 基本的有效性驗證功能,用于 Django 后臺和自動生成的表單。
字段 | 描述 |
---|---|
AutoField | 一個 IntegerField,根據(jù)可用的 ID 自動遞增 |
BigAutoField | 一個 64 位整數(shù),與 AutoField 很相似,但保證適合 1 到 9223372036854775807 的數(shù)字 |
BooleanField | 一個 true/false 字段。該字段的默認(rèn)表單部件是 CheckboxInput,或者如果 null=True 則是 NullBooleanSelect。當(dāng) Field.default 沒有定義時,BooleanField 的默認(rèn)值是 None。 |
CharField | 一個字符串字段,適用于小到大的字符串。對于大量的文本,使用 TextField CharField 有兩個額外的參數(shù):CharField.max_length(必須的。該字段的最大長度)、CharField.db_collation(可選的。該字段的數(shù)據(jù)庫字符序名稱) |
DateField | 一個日期,在 Python 中用一個 datetime.date 實例表示 可選參數(shù)auto_now(每次保存對象時,自動將該字段設(shè)置為現(xiàn)在)、auto_now_add(當(dāng)?shù)谝淮蝿?chuàng)建對象時,自動將該字段設(shè)置為現(xiàn)在) |
詳見:django官方文檔–字段類型
字段選項
以下只介紹Field類中的選項,拓展類每個都有獨特的選項,詳細(xì)參考Django文檔中每個類別的詳細(xì)介紹(例如, CharField (以及它的子類)需要接收一個 max_length 參數(shù),用以指定數(shù)據(jù)庫存儲 VARCHAR 數(shù)據(jù)時用的字節(jié)數(shù)。)
選型 | 描述 |
---|---|
null | 如果設(shè)置為 True,當(dāng)該字段為空時,Django 會將數(shù)據(jù)庫中該字段設(shè)置為 NULL。默認(rèn)為 False 。 |
blank | 如果設(shè)置為 True,該字段允許為空。默認(rèn)為 False。 |
choices | 一系列二元組,用作此字段的選項 CHOICES = [(‘FR’, ‘Freshman’),(‘SO’, ‘Sophomore’),] |
default | 該字段的默認(rèn)值 |
help_text | 額外的“幫助”文本,隨表單控件一同顯示。 |
primary_key | 如果設(shè)置為 True ,將該字段設(shè)置為該模型的主鍵 |
unique | 如果設(shè)置為 True,這個字段的值必須在整個表中保持唯一 |
除了 ForeignKey, ManyToManyField 和 OneToOneField,任何字段類型都接收一個可選的位置參數(shù) verbose_name,如果未指定該參數(shù)值, Django 會自動使用字段的屬性名作為該參數(shù)值,并且把下劃線轉(zhuǎn)換為空格。
關(guān)聯(lián)關(guān)系
顯然,關(guān)系型數(shù)據(jù)庫的強大之處在于各表之間的關(guān)聯(lián)關(guān)系。 Django 提供了定義三種最常見的數(shù)據(jù)庫關(guān)聯(lián)關(guān)系的方法:多對一,多對多,一對一。
多對一關(guān)聯(lián)
class ForeignKey(to, on_delete, **options)
一個多對一的關(guān)系。需要兩個位置參數(shù):模型相關(guān)的類和 on_delete 選項。
如果需要創(chuàng)建一個遞歸關(guān)系—— 一個與自己有多對一關(guān)系的對象
使用 models.ForeignKey(‘self’,on_delete=models.CASCADE)。
如果你需要在一個尚未定義的模型上創(chuàng)建關(guān)系,你可以使用模型的名稱,而不是模型對象本身:
例如,如果一個 Car 模型有一個制造者 Manufacturer --就是說一個 Manufacturer
制造許多輛車,但是每輛車都僅有一個制造者-- 那么使用下面的方法定義這個關(guān)系:
from django.db import models
class Manufacturer(models.Model):
# ...
pass
class Car(models.Model):
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
# ...
on_delete參數(shù)設(shè)置
當(dāng)一個由 ForeignKey 引用的對象被刪除時,Django 將模擬 on_delete 參數(shù)所指定的 SQL 約束的行為。
- CASCADE
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.RESTRICT)
級聯(lián)刪除
。Django 模擬了 SQL 約束 ON DELETE CASCADE 的行為,也刪除了包含 ForeignKey 的對象
。
Model.delete() 在相關(guān)的模型上沒有被調(diào)用,但是 pre_delete 和 post_delete 信號是為所有被刪除的對象發(fā)送的。
- PROTECT
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.PROTECT)
通過引發(fā) ProtectedError錯誤
,即 django.db.IntegrityError 的子類,防止刪除被引用對象。
- RESTRICT
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.RESTRICT)
這個在Django 3.1.以上版本使用
通過引發(fā) RestrictedError錯誤
( django.db.IntegrityError 的一個子類)來防止刪除被引用的對象。與 PROTECT 不同的是,如果被引用的對象也引用了一個在同一操作中被刪除的不同對象,但通過 CASCADE 關(guān)系,則允許刪除被引用的對象。
- SET_NULL
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.SET_NULL,null=True)
設(shè)置 ForeignKey 為空
;只有當(dāng) null 為 True 時,才有可能。
- SET_DEFAULT
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.SET_DEFAULT default=1)
將 ForeignKey 設(shè)置為默認(rèn)值
,必須為 ForeignKey 設(shè)置一個默認(rèn)值。
- SET()
#定義一個函數(shù)進行值得返回
def get_manufacturer()
return 1
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.SET(get_manufacturer),)
將 ForeignKey 設(shè)置為傳遞給 SET() 的值,如果傳遞了一個可調(diào)用的值,則為調(diào)用它的結(jié)果。在大多數(shù)情況下,為了避免在導(dǎo)入 models.py 時執(zhí)行查詢,傳遞一個可調(diào)用對象是必要的
- DO_NOTHING
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.DO_NOTHING)
不采取任何行動
。如果你的數(shù)據(jù)庫后端強制執(zhí)行引用完整性,這將導(dǎo)致一個 IntegrityError 除非你手動添加一個 SQL ON DELETE 約束條件到數(shù)據(jù)庫字段。
on_delete 的可能值可以在 django.db.models 中找到。文章來源:http://www.zghlxwxcb.cn/news/detail-796686.html
地區(qū)的自關(guān)聯(lián)實例
以下使用地區(qū)的自關(guān)聯(lián)查詢?yōu)閷嵗?span toymoban-style="hidden">文章來源地址http://www.zghlxwxcb.cn/news/detail-796686.html
#模型創(chuàng)建 model.py
class District(models.Model):
parent = models.ForeignKey(
"self",
null=True,
blank=True,
on_delete=models.CASCADE,
related_name="child", #
verbose_name="父級地區(qū)",
)
name = models.CharField(max_length=128, help_text="地區(qū)名稱", verbose_name="地區(qū)名稱")
level = models.IntegerField(default=0, help_text="地區(qū)級別", verbose_name="地區(qū)級別")
full_name = models.CharField(max_length=256, help_text="地區(qū)全名", verbose_name="地區(qū)全名")
def __str__(self):
return self.full_name
class Meta:
managed=True
verbose_name = "地區(qū)信息"
verbose_name_plural = verbose_name
#視圖調(diào)用模型以drf框架的視圖的使用APIView主
class CityCountyView(APIView):
"""
父級下二級地區(qū)信息獲取
"""
authentication_classes = [BasicAuthentication]
permission_classes = (AllowAny,)
@swagger_auto_schema(operation_description='父級下二級地區(qū)信息獲取', responses={200: {}})
def get(self, request, pk):
# 判斷有沒有緩存,有緩存使用緩存,沒有緩存去數(shù)據(jù)庫查詢存入緩存一天
sub_data = cache.get('sub_data_%s' % pk)
if not sub_data:
try:
# 獲取到前端傳過來的父級id 查詢出父級對象
parent_obj = District.objects.get(id=pk)
# 獲取對象的所有外鍵關(guān)聯(lián)的子級
sub_objs = parent_obj.child.all()
subs = []
# 組織數(shù)據(jù)
for sub in sub_objs:
subs.append({'id': sub.id, 'name': sub.name, })
sub_data = {'id': pk, 'name': parent_obj.name, 'subs': subs}
except Exception as e:
print(e)
return Response({'code': 400, 'errmsg': '查詢失敗'})
cache_key_name = 'sub_data_%s' % pk
cache.set(cache_key_name, sub_data, 3600 * 24) #
return Response({'code': 0, 'errmsg': 'ok', 'sub_data': sub_data})
動態(tài)生成模型類
#使用函數(shù)+class來定義
def getTaskDetailModel(table_name):
class MyCLass(models.Model):
task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='details', verbose_name='任務(wù)')
user_id = models.IntegerField(verbose_name='用戶ID')
created_time = models.DateTimeField(auto_now_add=True, verbose_name='創(chuàng)建時間')
is_complet = models.BooleanField(default=False, verbose_name='是否完成')
class Meta:
db_table = table_name
return MyCLass
#使用函數(shù)+type進行創(chuàng)建動態(tài)類
def create_task_detail_model(password_code):
classname = f'TaskDetail_{password_code}'
class Meta:
db_table = classname
return type(classname, (models.Model,), {
'task': models.ForeignKey(Task, on_delete=models.CASCADE, related_name='details', verbose_name='任務(wù)'),
'user_id': models.IntegerField(verbose_name='用戶ID'),
'created_time': models.DateTimeField(auto_now_add=True, verbose_name='創(chuàng)建時間'),
'is_complet': models.BooleanField(default=False, verbose_name='是否完成'),
'__str__': lambda self: f"{self.task.password_code} - {self.user_id}",
'Meta': Meta,
'__module__': __name__,
})
到了這里,關(guān)于django中orm模型類多種用法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!