06.orm模型層
ORM模型層
01.常用字段
<1> CharField
字符串字段, 用於較短的字符串.
CharField 要求必須有一個參數 maxlength, 用於從數據庫層和Django校驗層限制該字段所允許的最大字符數.
<2> IntegerField
#用於保存一個整數.
<3> FloatField
一個浮點數. 必須 提供兩個參數:
參數 描述:
max_digits 總位數(不包括小數點和符號)
decimal_places 小數位數
舉例來說, 要保存最大值為 999 (小數點後保存2位),你要這樣定義字段:
models.FloatField(..., max_digits=5, decimal_places=2)
要保存最大值一百萬(小數點後保存10位)的話,你要這樣定義:
models.FloatField(..., max_digits=19, decimal_places=10)
admin 用一個文本框(<input type="text">)表示該字段保存的數據.
<4> AutoField
一個 IntegerField, 添加記錄時它會自動增長. 你通常不需要直接使用這個字段;
自定義一個主鍵:my_id=models.AutoField(primary_key=True)
如果你不指定主鍵的話,系統會自動添加一個主鍵字段到你的 model.
<5> BooleanField
A true/false field. admin 用 checkbox 來表示此類字段.
<6> TextField
一個容量很大的文本字段.
admin 用一個 <textarea> (文本區域)表示該字段數據.(一個多行編輯框).
<7> EmailField
一個帶有檢查Email合法性的 CharField,不接受 maxlength 參數.
<8> DateField
一個日期字段. 共有下列額外的可選參數:
Argument 描述
auto_now 當對象被保存時,自動將該字段的值設置為當前時間.通常用於表示 "last-modified" 時間戳.
auto_now_add 當對象首次被創建時,自動將該字段的值設置為當前時間.通常用於表示對象創建時間.
(僅僅在admin中有意義..)
<9> DateTimeField
一個日期時間字段. 類似 DateField 支持同樣的附加選項.
<10> ImageField
類似 FileField, 不過要校驗上傳對象是否是一個合法圖片.#它有兩個可選參數:height_field和width_field,
如果提供這兩個參數,則圖片將按提供的高度和寬度規格保存.
<11> FileField
一個文件上傳字段.
要求一個必須有的參數: upload_to, 一個用於保存上載文件的本地文件系統路徑. 這個路徑必須包含 strftime #formatting,
該格式將被上載文件的 date/time
註意:在一個 model 中使用 FileField 或 ImageField 需要以下步驟:
1)在你的 settings 文件中, 定義一個完整路徑給 MEDIA_ROOT 以便讓 Django在此處保存上傳文件.
(出於性能考慮,這些文件並不保存到數據庫.) 定義MEDIA_URL 作為該目錄的公共 URL. 要確保該目錄對
WEB服務器用戶帳號是可寫的.
2)在你的 model 中添加 FileField 或 ImageField, 並確保定義了 upload_to 選項,以告訴 Django
使用 MEDIA_ROOT 的哪個子目錄保存上傳文件.你的數據庫中要保存的只是文件的路徑(相對於 MEDIA_ROOT).
出於習慣你一定很想使用 Django 提供的 get_<#fieldname>_url 函數.舉例來說,如果你的 ImageField
叫作 mug_shot, 你就可以在模板中以 {{ object.#get_mug_shot_url }} 這樣的方式得到圖像的絕對路徑.
02.字段選項:常用的參數
(0)null
如果為True,Django 將用NULL 來在數據庫中存儲空值。 默認值是 False.
(1)blank
如果為True,該字段允許不填。默認為False。
要註意,這與 null 不同。null純粹是數據庫範疇的,而 blank 是數據驗證範疇的。
如果一個字段的blank=True,表單的驗證將允許該字段是空值。如果字段的blank=False,該字段就是必填的。
(2)default
字段的默認值。可以是一個值或者可調用對象。如果可調用 ,每有新對象被創建它都會被調用。
(3)primary_key
如果為True,那麽這個字段就是模型的主鍵。如果你沒有指定任何一個字段的primary_key=True,
Django 就會自動添加一個IntegerField字段做為主鍵,所以除非你想覆蓋默認的主鍵行為,
否則沒必要設置任何一個字段的primary_key=True。
(4)unique
如果該值設置為 True, 這個數據字段的值在整張表中必須是唯一的
(5)choices
由二元組組成的一個可叠代對象(例如,列表或元組),用來給字段提供選擇項。 如果設置了choices ,默認的表單將是一個選擇框而不是標準的文本框,而且這個選擇框的選項就是choices 中的選項。
這是一個關於 choices 列表的例子:
YEAR_IN_SCHOOL_CHOICES = (
(‘FR‘, ‘Freshman‘),
(‘SO‘, ‘Sophomore‘),
(‘JR‘, ‘Junior‘),
(‘SR‘, ‘Senior‘),
(‘GR‘, ‘Graduate‘),
)
每個元組中的第一個元素,是存儲在數據庫中的值;第二個元素是在管理界面或 ModelChoiceField 中用作顯示的內容。 在一個給定的 model 類的實例中,想得到某個 choices 字段的顯示值,就調用 get_FOO_display 方法(這裏的 FOO 就是 choices 字段的名稱 )。例如:
1 from django.db import models
2
3 class Person(models.Model):
4 SHIRT_SIZES = (
5 (‘S‘, ‘Small‘),
6 (‘M‘, ‘Medium‘),
7 (‘L‘, ‘Large‘),
8 )
9 name = models.CharField(max_length=60)
10 shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
11
12
13 >>> p = Person(name="Fred Flintstone", shirt_size="L")
14 >>> p.save()
15 >>> p.shirt_size
16 ‘L‘
17 >>> p.get_shirt_size_display()
18 ‘Large‘
03.settings配置中
給項目根目錄下的__init__添加
import pymysql
pymysql.install_as_MySQLdb()
*如果報錯如下:
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required;
MySQLclient目前只支持到python3.4,因此如果使用的更高版本的python,需要修改如下:
通過查找路徑C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql 這個路徑裏的文件把
if version < (1, 3, 3):
raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
註釋掉 就OK了。
*如果想打印orm轉換過程中的sql,需要在settings中進行如下配置:
1 LOGGING = { 2 ‘version‘: 1, 3 ‘disable_existing_loggers‘: False, 4 ‘handlers‘: { 5 ‘console‘:{ 6 ‘level‘:‘DEBUG‘, 7 ‘class‘:‘logging.StreamHandler‘, 8 }, 9 }, 10 ‘loggers‘: { 11 ‘django.db.backends‘: { 12 ‘handlers‘: [‘console‘], 13 ‘propagate‘: True, 14 ‘level‘:‘DEBUG‘, 15 }, 16 } 17 }
04.添加表紀錄
<1>一對一:
方式1
# create方法的返回值book_obj就是插入book表中的python葵花寶典這本書籍紀錄對象
book_obj=Book.objects.create(title="python葵花寶典",state=True,price=100,publish="蘋果出版社",pub_date="2012-12-12")
方式2
book_obj=Book(title="python葵花寶典",state=True,price=100,publish="蘋果出版社",pub_date="2012-12-12")
book_obj.save()
<2>一對多:
方式1:找到關聯表的對象
publish_obj=Publish.objects.get(nid=1)
book_obj=Book.objects.create(title="金",publishDate="2012-12-12",price=100,publish=publish_obj)
方式2:找到關聯表的字段_id
book_obj=Book.objects.create(title="金",publishDate="2012-12-12",price=100,publish_id=1)
<3>多對多:用add進行多對多的關聯創建
1 # 當前生成的書籍對象
2 book_obj=Book.objects.create(title="追風箏的人",price=200,publishDate="2012-11-12",publish_id=1)
3 # 為書籍綁定的做作者對象
4 yuan=Author.objects.filter(name="yuan").first() # 在Author表中主鍵為2的紀錄
5 egon=Author.objects.filter(name="alex").first() # 在Author表中主鍵為1的紀錄
6
7 # 綁定多對多關系,即向關系表book_authors中添加紀錄
8 book_obj.authors.add(yuan,egon) # 將某些特定的 model 對象添加到被關聯對象集合中。 ======= book_obj.authors.add(*[])
9
10 *多對多關系其他常用API
11 -1book_obj.authors.remove() # 將某個特定的對象從被關聯對象集合中去除。 ====== book_obj.authors.remove(*[])
12 對於ForeignKey對象,這個方法僅在null=True時存在。
13
14 -2book_obj.authors.clear() #清空被關聯對象集合
15 註意這樣不會刪除對象 —— 只會刪除他們之間的關聯。就像 remove() 方法一樣,clear()只能在 null=True的ForeignKey上被調用。
16
17 -3book_obj.authors.set() #先清空再設置
*延伸:
1 # 1 *[]的使用
2
3 book_obj = Book.objects.get(id=1)
4 author_list = Author.objects.filter(id__gt=2)
5 book_obj.authors.add(*author_list)
6
7 # 2 直接綁定主鍵
8 book_obj.authors.add(*[1,3]) # 將id=1和id=3的作者對象添加到這本書的作者集合中
9 # 應用: 添加或者編輯時,提交作者信息時可以用到.
05.查詢表紀錄:查詢API
<1> all(): 查詢所有結果
<2> filter(**kwargs): 它包含了與所給篩選條件相匹配的對象
<3> get(**kwargs): 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,
如果符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
<4> exclude(**kwargs): 它包含了與所給篩選條件不匹配的對象
<5> order_by(*field): 對查詢結果排序
<6> reverse(): 對查詢結果反向排序
<8> count(): 返回數據庫中匹配查詢(QuerySet)的對象數量。
<9> first(): 返回第一條記錄
<10> last(): 返回最後一條記錄
<11> exists(): 如果QuerySet包含數據,就返回True,否則返回False
<12> values(*field): 返回一個ValueQuerySet——一個特殊的QuerySet,運行後得到的並不是一系列
model的實例化對象,而是一個可叠代的字典序列
<13> values_list(*field): 它與values()非常相似,它返回的是一個元組序列,values返回的是一個字典序列
<14> distinct(): 從返回結果中剔除重復紀錄
基於雙下劃線的模糊查詢
1 Book.objects.filter(price__in=[100,200,300]) #in內
2 Book.objects.filter(price__gt=100) #gt大於
3 Book.objects.filter(price__lt=100) #lt小於
4 Book.objects.filter(price__range=[100,200]) #range範圍
5 Book.objects.filter(title__contains="python")
6 Book.objects.filter(title__icontains="python") # 大小寫不明感
7 Book.objects.filter(title__startswith="py") #startswith開頭
8 Book.objects.filter(pub_date__year=2012) # _date__year拿到月份
9 startswith,istartswith, endswith, iendswith # 加了i的都為否定語句
06.刪除表記錄
方法就是 delete()。它運行時立即刪除對象而不返回任何值。例如:
Entry.objects.filter(pub_date__year=2005).delete()
07.修改表紀錄
Book.objects.filter(title__startswith="py").update(price=120)
此外,update()方法對於任何結果集(QuerySet)均有效,這意味著你可以同時更新多條記錄update()
方法會返回一個整型數值,表示受影響的記錄條數。
08.查詢表記錄
<1>對象obj查詢
先查找一個obj對象,用get方法獲取,或者用first
用此obj對象進行(正向看字段,反向看表名__set.all())
其中在一對一的情況,可直接拿到obj,再通過.屬性拿到相應值
一對多的情況,正向可拿到obj,再通過.屬性拿到相應值/反向需要.all()拿到queryset進行遍歷或者values_list()拿到需要的值
多對多的情況,正反向都需要.all(),再通過遍歷拿到obj
<2>雙下劃線__查詢
公式:需要的表.objects.filter(通過__拿到關鍵值).values_list(‘通過__拿到各種需求的值‘,‘‘...)
<3>聚合查詢aggregate
from django.db.models import Min, Max, Count, Sum
深度查詢 .aggregate(自己賦值=Count/Max...‘通過__拿到各種需求的值‘)
<4>分組查詢annotate
每一xxx可以使用,相當於sql裏的group
多於聚合查詢混合使用
深度查詢 .annotate(自己賦值=Count(‘通過__拿到各種需求的值‘))
<5>排序order_by
.order_by(‘num_authors‘)
<6>F與Q
F:對單個對象中多個值進行比較操作
from django.db.models import F
# 查詢評論數大於收藏數2倍的書籍
Book.objects.filter(commnetNum__lt=F(‘keepNum‘)*2)
# 將每一本書的價格提高30元:
Book.objects.all().update(price=F("price")+30)
Q:filter() 等方法中的關鍵字參數查詢都是一起進行“AND” 的,要進行& |等復雜操作需要用Q
from django.db.models import Q
# or操作
bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
06.orm模型層