Python之django框架模型(models)詳解
標簽: Django入門
第一部分:模型類介紹
1.1 定義屬性
Django根據屬性的類型確定以下信息:
- 當前選擇的數據庫支持字段的類型
- 渲染管理表單時使用的默認html控件
- 在管理站點最低限度的驗證
django會為表創建自動增長的主鍵列,每個模型只能有一個主鍵列,如果使用選項設置某屬性為主鍵列后django不會再創建自動增長的主鍵列。
默認創建的主鍵列屬性為id,可以使用pk代替,pk全拼為primary key。
注意:pk是主鍵的別名,若主鍵名為id2,那么pk是id2的別名。
屬性命名限制:
- 不能是python的保留關鍵字。
- 不允許使用連續的下劃線,這是由django的查詢方式決定的,在后面會詳細講解查詢。
- 定義屬性時需要指定字段類型,通過字段類型的參數指定選項,語法如下:
屬性=models.字段類型(選項)
1.2 字段類型
使用時需要引入django.db.models包,字段類型如下:
- AutoField:自動增長的IntegerField,通常不用指定,不指定時Django會自動創建屬性名為id的自動增長屬性。(必須填入參數primary_key=True)
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)
- BooleanField:布爾字段,值為True或False。
- NullBooleanField:支持Null、True、False三種值。
- CharField(max_length=字符長度):字符串。
- 參數max_length表示最大字符個數。
- TextField:大文本字段,一般超過4000個字符時使用。
- IntegerField:整數。
- DecimalField(max_digits=None, decimal_places=None):十進制浮點數。
- 參數max_digits表示總位數。
- 參數decimal_places表示小數位數。
- FloatField:浮點數。
- DateField[auto_now=False, auto_now_add=False]):日期。
- 參數auto_now表示每次保存對象時,自動設置該字段為當前時間,用于"最后一次修改"的時間戳,它總是使用當前日期,默認為false。
- 參數auto_now_add表示當對象第一次被創建時自動設置當前時間,用于創建的時間戳,它總是使用當前日期,默認為false。
- 參數auto_now_add和auto_now是相互排斥的,組合將會發生錯誤。
- TimeField:時間,參數同DateField。
- DateTimeField:日期時間,參數同DateField。
- FileField:上傳文件字段。
參數 | 說明 |
---|---|
upload_to = “” | 上傳文件的保存路徑如:upload_to = "uploads/%Y/%m/%d/“ |
- ImageField:繼承于FileField,對上傳的內容進行校驗,確保是有效的圖片。
參數 | 說明 |
---|---|
upload_to = “” | 上傳文件的保存路徑 |
storage = None | 存儲組件,默認django.core.files.storage.FileSystemStorage |
width_field=None | 上傳圖片的高度保存的數據庫字段名(字符串) |
height_field=None | 上傳圖片的寬度保存的數據庫字段名(字符串) |
1.3 選項
通過選項實現對字段的約束,選項如下:
- null:如果為True,表示允許為空,默認值是False。
- blank:如果為True,則該字段允許為空白,默認值是False。
- 對比:null是數據庫范疇的概念,blank是表單驗證范疇的。
- db_column:字段的名稱,如果未指定,則使用屬性的名稱。
- db_index:若值為True, 則在表中會為此字段創建索引,默認值是False。
- default:默認值。
- primary_key:若為True,則該字段會成為模型的主鍵字段,默認值是False,一般作為AutoField的選項使用。
- unique:如果為True, 這個字段在表中必須有唯一值,默認值是False。
1.4 關聯數據 on_delete
- CASCADE:這就是默認的選項,級聯刪除。
- PROTECT: 保護模式,如果采用該選項,刪除的時候,會拋出
ProtectedError
錯誤。 - SET_NUL
: 置空模式,刪除的時候,外鍵字段被設置為空,前提就是
blank=True, null=True`,定義該字段的時候,允許為空。 - SET_DEFAULT: 置默認值,刪除的時候,外鍵字段設置為默認值,所以定義外鍵的時候注意加上一個默認值。
- SET(): 自定義一個值,該值當然只能是對應的實體了
**官方案例**
def get_sentinel_user():
return get_user_model().objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.SET(get_sentinel_user),
)
1.5 關聯數據 on_delete
- db_table: 指定表名
- abstract: 指定是否為抽象類
- ordering: 排序; 字符串前加-表示倒序,不加-表示正序
- verbose_name: 讓字段可讀
- verbose_name_plural:讓復數字段可讀
class User(models.Model):
EDU_CHOICES = (
('1', '高中'),
('2', '大專'),
('3', '本科'),
('4', '碩士'),
('5', '博士')
)
GENDER_CHOICES = (
('1', '男'),
('2', '女'))
nickname = models.CharField(verbose_name='昵稱', max_length=20, blank=False)
password = models.CharField(verbose_name='密碼', max_length=40, blank=False)
tel = models.CharField(verbose_name='手機號碼', max_length=11, blank=False)
edu = models.CharField(verbose_name='學歷', max_length=1, choices=EDU_CHOICES)
gender = models.CharField(verbose_name='性別', max_length=1, choices=GENDER_CHOICES)
class Meta:
db_table = 'mt_users'
verbose_name = '用戶管理'
verbose_name_plural = verbose_name
ordering = ['-id']
第二部分:模型查詢
2.1 精確查詢
exact:表示判等。
list=Article.objects.filter(id__exact=1)
可簡寫為:
list=Article.objects.filter(id=1)
2.2 根據主鍵查詢
Article.objects.get(pk=1)
注意:使用get()方法和使用filter()方法然后通過[0]的方式分片,有著不同的地方。看似兩者都是獲取單一對象。但是,如果在查詢時沒有匹配到對象,那么get()方法將拋出DoesNotExist異常。這個異常是模型類的一個屬性,在上面的例子中,如果不存在主鍵為1的Entry對象,那么Django將拋出
Entry.DoesNotExist
異常。類似地,在使用get()方法查詢時,如果結果超過1個,則會拋出MultipleObjectsReturned異常,這個異常也是模型類的一個屬性。
2.3 模糊查詢
contains:是否包含。
list = Article.objects.filter(btitle__contains='新')
startswith、endswith:以指定值開頭或結尾。
list = Article.objects.filter(btitle__endswith='哈哈')
以上運算符都區分大小寫,在這些運算符前加上i表示不區分大小寫,如iexact、icontains、istartswith、iendswith.
2.4 是否為空查詢
isnull:是否為null。
list = Article.objects.filter(title__isnull=False)
2.5 范圍查詢
in:是否包含在范圍內。
list = Article.objects.filter(id__in=[1, 3, 5])
2.6 比較查詢
gt、gte、lt、lte:大于、大于等于、小于、小于等于。
list = Article.objects.filter(id__gt=3)
不等于
不等于的運算符,使用exclude()過濾器。
list = Article.objects.exclude(id=3)
2.7 日期查詢
year、month、day、week_day、hour、minute、second:對日期時間類型的屬性進行運算。
list = Article.objects.filter(create_time__year=2019)
查詢2019年1月1日后發表的文章。
list = Article.objects.filter(create_time__gt=date(2019, 1, 1))
2.8 F對象
兩個屬性做比較
例:查詢閱讀量大于等于評論量的文章。
from django.db.models import F
...
list = Article.objects.filter(vnum__gte=F('cnum'))
可以在F對象上使用算數運算。
例:查詢閱讀量大于2倍評論量的文章。
list = Article.objects.filter(bread__gt=F('bcomment') * 2)
2.9 Q對象
并且關系
例:查詢閱讀量大于20,并且編號小于3的文章。
list=Article.objects.filter(vnum__gt=20,id__lt=3)
或
list=Article.objects.filter(vnum__gt=20).filter(id__lt=3)
例:查詢閱讀量大于20的文章,改寫為Q對象如下。
from django.db.models import Q
...
list = Article.objects.filter(Q(vnum__gt=20))
例:查詢閱讀量大于20,或編號小于3的文章,只能使用Q對象實現
list = Article.objects.filter(Q(vnum__gt=20) | Q(id__lt=3))
例:查詢編號不等于3的文章。
list = Article.objects.filter(~Q(pk=3))
2.10 聚合函數
使用aggregate()過濾器調用聚合函數。聚合函數包括:Avg,Count,Max,Min,Sum,被定義在django.db.models中。
例:查詢文章的總閱讀量。
from django.db.models import Sum
...
list = Article.objects.aggregate(Sum('vnum'))
注意aggregate的返回值是一個字典類型,格式如下:
{'聚合類小寫__屬性名':值}
如:{'sum__vnum':3}
第三部分:Django查詢集QuerySet及兩大特性
3.1、概念
查詢集表示從數據庫中獲取的對象集合。
Django的ORM中存在查詢集的概念。
查詢集,也稱查詢結果集、QuerySet,表示從數據庫中獲取的對象集合。
當調用如下過濾器方法時,Django會返回查詢集(而不是簡單的列表):
- all():返回所有數據。
- filter():返回滿足條件的數據。
- exclude():返回滿足條件之外的數據。
- order_by():對結果進行排序。
也就意味著查詢集可以含有零個、一個或多個過濾器。過濾器基于所給的參數限制查詢的結果。
從SQL的角度講,查詢集與select語句等價,過濾器像where、limit、order by子句。
判斷某一個查詢集中是否有數據:
- exists():判斷查詢集中是否有數據,如果有則返回True,沒有則返回False。
3.2、查詢集兩大特性
3.2.1 惰性查詢
只有在實際使用查詢集中的數據的時候,才會發生對數據庫的真正查詢,
list=Article.objects.all()
3.2.2 查詢集緩存
當使用的是同一個查詢集時,第一次的時候會發生實際數據庫的查詢,然后把結果緩存起來,之后再使用這個查詢集時,使用的是緩存中的結果集
情況一:不重用緩存,每次查詢都會與數據庫進行一次交互,增加了數據庫的負載。
from .models import Article
[article.id for book in Article.objects.all()]
[article.id for book in Article.objects.all()]
情況二:經過存儲后,可以重用查詢集,第二次使用緩存中的數據
list=Article.objects.all()
[article.id for article in list]
[article.id for article in list]
3.3、切片
list=Article.objects.all()[0:2]
第四部分:Django關聯模型查詢
4.1 模型類關系
關系型數據庫的關系包括三種類型:
- ForeignKey:一對多,將字段定義在多的一端中。
- ManyToManyField:多對多,將字段定義在任意一端中。
- OneToOneField:一對一,將字段定義在任意一端中。
- 可以維護遞歸的關聯關系,使用’self’指定,詳見"自關聯"。
4.2 一對多關系
新聞和分類模型
# 分類表
class Category(models.Model):
title = models.CharField(max_length=20)
position = models.IntegerField(default=1) # 用來排序
isshow = models.BooleanField(default=True) # 用于是否展示
isdelete = models.BooleanField(default=False) # 用于是否刪除
create_time = models.DateTimeField(auto_now_add=True) # 用于表示創建時間
update_time = models.DateTimeField(auto_now=True) # 用于表示更新時間
def __str__(self):
return self.title
#文章表
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(max_length=5000)
Category = models.ForeignKey(to=Category,on_delete=models.CASCADE) # 一對多 必須寫在多的里面
def __str__(self):
return self.title
4.3 多對多關系
新聞和標簽模型
# 標簽
class Tag(models.Model):
title = models.CharField(max_length=20) # 標簽名字
isdelete = models.BooleanField(default=False) # 用于是否刪除
create_time = models.DateTimeField(auto_now_add=True) # 用于表示創建時間
update_time = models.DateTimeField(auto_now=True) # 用于表示更新時間
# 文章表
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField(max_length=5000)
tag = models.ManyToManyField(to=Tag) # 多對多寫在哪里都可以
def __str__(self):
return self.title
4.4 自關聯
省市區模型
#定義地區模型類,存儲省、市、區縣信息
class Area(models.Model):
title=models.CharField(max_length=30)#名稱
parent=models.ForeignKey('self',null=True,blank=True)#關系
4.5 查詢
- 一對多關聯查詢
category = Category.objects.get(id=1)
category.article_set.all()
- 多到一關聯查詢:
article = Article.objects.get(id=1)
article.category
- 多對多關聯查詢->正向查詢
article = Article.objects.get(id=1)
article.tag.all() # 取一篇文章的所有標簽
- 多對多關聯查詢->反向查詢
tag = Tag.objects.get(id=1)
tag.article_set.all()
- 反向查詢簡化
可以在ForeignKey字段的定義中,category = ForeignKey(Category, on_delete=models.CASCADE, related_name=’articles’)`
c = Category.objects.get(id=1)
c.articles.all()
第五部分:Django關聯模型查詢常用方法
5.1 返回新QuerySet的部分方法
方法名 | 解釋 |
---|---|
all() | 獲取所有的對象 |
filter() | 過濾查詢對象。 |
exclude() | 排除滿足條件的對象 |
annotate() | 使用聚合函數 |
order_by() | 對查詢集進行排序 |
reverse() | 反向排序 |
distinct() | 對查詢集去重 |
values() | 返回包含對象具體值的字典的QuerySet |
values_list() | 與values()類似,只是返回的是元組而不是字典 |
none() | 創建空的查詢集 |
5.2 不返回新QuerySet的部分方法
方法名 | 解釋 |
---|---|
get() | 獲取單個對象 |
first() | 獲取第一個對象 |
last() | 獲取最后一個對象 |
create() | 創建對象,無需save() |
update() | 批量更新對象 |
delete() | 批量刪除對象 |
count() | 統計對象的個數 |
aggregate() | 聚合操作 |
exists() | 判斷queryset中是否有對象 |
get_or_create() | 查詢對象,如果沒有找到就新建對象 |
update_or_create() | 更新對象,如果沒有找到就創建對象 |
latest() | 獲取最近的對象 |
earliest() | 獲取最早的對象 |
智能推薦
Django之models字段屬性
目錄 常用字段 AutoField IntegerField CharField 自定義及使用char DateField DateTimeField 字段合集 字段參數 null unique db_index default DateField和DateTimeField auto_now_add auto_now 關系字段 ForeignKey 字段參數 to to_field on_del...
Python框架Django -- 02 模型
一、完善案例 1、完成根據圖書顯示圖書下所有英雄的功能 (1)、在 booktest/views.py 中編寫根據圖書id查詢英雄信息的函數 (2)、在 booktest/urls.py 中添加url和函數的映射 (3)、編寫模版文件 (4)、瀏覽器測試 2、切換到MySQL數據庫 (1)、在虛擬環境中安裝MySQLdb的包 安裝pymysql包 在 test1/__init__.py 中加入以下...
Python Django框架學習06:Django 模型
Django 對各種數據庫提供了很好的支持,包括:PostgreSQL、MySQL、SQLite、Oracle。 Django 為這些數據庫提供了統一的調用API。 我們可以根據自己業務需求選擇不同的數據庫。 MySQL 是 Web 應用中最常用的數據庫。本章節我們將以 Mysql 作為實例進行介紹。你可以通過本站的 MySQL 教程 了解更多Mysql的基礎知識。 如果你沒安...
【Django 007】數據模型models數據庫交互詳解
企業開發中,通常都是從數據定義開始一個項目,所以我們也從models開始深入了解一下。 我是T型人小付,一位堅持終身學習的互聯網從業者。喜歡我的博客歡迎在csdn上關注我,如果有問題歡迎在底下的評論區交流,謝謝。 文章目錄 環境搭建 ORM 數據類型的映射 Models中的數據類型 約束條件 元選項 實際操作(數據類型映射) 模型成員objects 實際操作(模型成員objects) 別的插入數據...
Django 之 contenttypes 框架詳解
Django 高級實戰編程 視頻分享地址: https://study.163.com/course/introduction/1209407824.htm?share=2&shareId=400000000535031 使用上面的鏈接地址進入,聯系QQ 1064468942 可獲得 部分 學費退還 喔, 實際支出 將少于 所標識的價格 contenttypes框架 Django除了我們常...
猜你喜歡
Python篇-Django框架詳解
一 : 科普一分鐘 Django 這個Web框架學習過的人無不知曉它的強大. Django是一個開放源代碼的Web應用框架,由Python寫成,采用了MT'V的框架模式.即Model,View,Template組成.許多成功的網站和APP都基于Django.說到底,其實Django內部就是對 Socket 連接的強大封裝. Django.jpg 二:Django配置和創建 創建 在這...
Django框架學習7--models
django與用戶進行交互,頁面一旦關閉,或服務器重啟,一切都將回到原始狀態。 所以需要使用數據庫對用戶操作數據進行保存,Django通過自帶的ORM框架操作數據庫,并且原生支持輕量級的sqlite3數據庫。 1.django使用mysql配置 如果使用其他數據庫,需要自己進行settings.py中進行配置。mysql的配置如下: 2.django與mysql交互 (1)創建數據庫的表類,類名代...
Django模型層(models.py)之顯示數據庫
pycharm在右側顯示數據庫,便于管理和查看,那么怎么在右側顯示呢? 實現效果: 實現步驟: 測試連接時,可能會出現沒安裝下圖的情況,安裝就好了 可能會報錯: 解決: 更改mysql時區(American的時區和我們的時區不同) 1.在終端中使用管理員身份登錄mysql 2.顯示時區 3.更改時區 4.退出登錄,重新登錄mysql查看時區是否被更改 5.重新到pycharm中測試連接,發現連接成...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...