Django模型操作常用方法總結
Django模型操作常用方法總結:
1.Save()
基本方法:object.save()
save顧名思義是儲存的意思,在django中既可以進行新增也可以進行修改操作。具體判定的演算法如下:
1.如果物件的主鍵屬性為一個求值為True的值(例如,非None值或非空字串),Django將執行UPDATE。
2.如果物件的主鍵屬性沒有設定或者UPDATE沒有更新任何記錄,Django將執行INSERT。
Save函式可跟引數如下:
Model.save([force_insert=False,
force_update=False, using=DEFAULT_DB_ALIAS, update_fields
高階方法:重寫Save()
重寫的方式是覆蓋模型的方法
1.新增其他操作
defsave(self,*args,**kwargs):do_something()super(YourModel, self).save(*args,**kwargs) # Call the "real" save() method.do_something_else()
2.新增判斷條件
defsave(self,*args,**kwargs):ifself.name
=="Yoko Ono's blog":return # Yoko shall never have her own blog!
注意:批量操作中被覆蓋的模型方法不會被呼叫
2.返回新的查詢集的方法
filter
filter(**kwargs):返回一個新的QuerySet,包含與給定的查詢引數匹配的物件。其中查詢的引數(**kwargs)應該滿足欄位查詢中的格式。在底層的SQL語句中,多個引數通過AND連線。
exclude
返回一個新的QuerySet,它包含不滿足給定的查詢引數的物件。在底層的SQL語句中,多個引數通過AND連線,然後所有的內容放入
例如:
Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
等價於SQL:
SELECT ... WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
不過它的嚴格寫法是:
Entry.objects.exclude(pub_date__gt=datetime.date(2005,1,3)).exclude(headline='Hello')
等價於SQL:
SELECT ... WHERE NOT pub_date > '2005-1-3' AND NOT headline = 'Hello'
Annotate
使用提供的查詢表示式Annotate 查詢集中的每個物件。查詢表示式可以是一個簡單的值、模型(或關聯模型)欄位的一個引用或對查詢集中的物件一個聚合函式(平均值、和等)。
例如,如果你正在操作一個Blog列表,你可能想知道每個Blog有多少Entry:>>> fromdjango.db.models importCount>>> q= Blog.objects.annotate(Count('entry'))# The name of the first blog>>> q[0].name'Blogasaurus'# The number of entries on the first blog>>> q[0].entry__count42
order_by
order_by(*fields):預設情況下,QuerySet根據模型Meta類的ordering選項排序。你可以使用order_by方法給每個QuerySet指定特定的排序。
預設情況下,QuerySet 根據模型Meta類的ordering選項排序。你可以使用order_by方法給每個QuerySet指定特定的排序。
例如:
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
上面的結果將按照pub_date 降序排序,然後再按照headline升序排序。"-pub_date"前面的負號表示降序排序
若要按照另外一個模型中的欄位排序,可以使用查詢關聯模型時的語法。即通過欄位的名稱後面跟上兩個下劃線(__),再跟上新模型中的欄位的名稱,直至你希望連線的模型。例如:
Entry.objects.order_by('blog__name', 'headline')
reverse
reverse() 方法反向排序QuerySet中返回的元素。第二次呼叫reverse()將恢復到原有的排序。
如要獲取QuerySet 中最後五個元素,你可以這樣做:
my_queryset.reverse()[:5]
注意,這與Python 中從一個序列的末尾進行切片有點不一樣。上面的例子將首先返回最後一個元素,然後是倒數第二個元素,以此類推。如果我們有一個Python序列,當我們檢視seq[-5:]時,我們將一下子得到倒數五個元素。Django不支援這種訪問模型(從末尾進行切片),因為它不可能利用SQL高效地實現。
同時還要注意,reverse() 應該只在一個已經定義排序的QuerySet上呼叫(例如,在一個定義了預設排序的模型上,或者使用order_by()的時候)。如果QuerySet沒有定義排序,呼叫reverse()將不會有任何效果(在呼叫reverse()之前沒有定義排序,那麼呼叫之後仍保持沒有定義)。
distinct
返回一個在SQL 查詢中使用SELECT DISTINCT的新QuerySet。它將去除查詢結果中重複的行。
values
返回一個ValuesQuerySet ——QuerySet 的一個子類,迭代時返回字典而不是模型例項物件。
每個字典表示一個物件,鍵對應於模型物件的屬性名稱。
下面的例子將values() 與普通的模型物件進行比較:
# This list contains a Blog object.
>>> Blog.objects.filter(name__startswith='Beatles')
[<Blog: Beatles Blog>]
# This list contains a dictionary.
>>> Blog.objects.filter(name__startswith='Beatles').values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]
3.不返回查詢集的方法
create
create(**kwargs)是一個在一步操作中同時建立物件並且儲存的便捷方法.所以:
p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
和:
p = Person(first_name="Bruce", last_name="Springsteen")
p.save(force_insert=True)
是等同的.
get_or_create
一個通過給出的kwargs 來查詢物件的便捷方法(如果你的模型中的所有欄位都有預設值,可以為空),需要的話建立一個物件。
返回一個由(object, created)組成的元組,元組中的object是一個查詢到的或者是被建立的物件, created是一個表示是否建立了新的物件的布林值。
這主要用作樣板程式碼的一種快捷方式。例如:
try:
obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
obj.save()
如果模型的欄位數量較大的話,這種模式就變的非常不易用了。上面的示例可以用get_or_create()重寫:
obj,created=Person.objects.get_or_create(first_name='John',last_name='Lennon',defaults={'birthday': date(1940, 10, 9)})
count()
返回在資料庫中對應的 QuerySet.物件的個數。count() 永遠不會引發異常。
例如:
# Returns the total number of entries in the database.
Entry.objects.count()
# Returns the number of entries whose headline contains 'Lennon'
Entry.objects.filter(headline__contains='Lennon').count()
latest
latest(field_name=None)
通過實踐返回表中最近一條記錄,使用表中欄位名作為查詢的日期欄位
下面這個例子返回Entry表中按pub_date欄位排序的最新的一條記錄
Entry.objects.latest('pub_date')
earliest
earliest(field_name=None)
工作方式和上面的latest相同,只是取得的值相反
first
first()
返回結果集的第一個物件, 當沒有找到時返回None.如果QuerySet 沒有設定排序,則將會自動按主鍵進行排序
例子:
p = Article.objects.order_by('title', 'pub_date').first()
說明:first() 是一個簡便方法 下面這個例子和上面的程式碼效果是一樣
try:
p = Article.objects.order_by('title', 'pub_date')[0]
except IndexError:
p = None
last
last()
工作方式類似first(),只是返回的是查詢集中最後一個物件。
exists
exists()
如果QuerySet 包含任何結果,則返回True,否則返回False。它會試圖用最簡單和最快的方法完成查詢,但它執行的方法與普通的QuerySet查詢確實幾乎相同。
exists() 用於搜尋物件是否在QuerySet中以及QuerySet是否存在任何物件,特別是QuerySet比較大的時候。
查詢具有唯一性欄位(例如primary_key)的模型是否在一個QuerySet中的最高效的方法是:
entry = Entry.objects.get(pk=123)
if some_queryset.filter(pk=entry.pk).exists():
print("Entry contained in queryset")
update
update(**kwargs)
為特定的欄位執行SQL更新查詢,然後返回受影響的行數。
例如,將2010年釋出的所有blog下entry中的評論關了,可以執行下面操作
>>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False)
delete
delete()
執行SQL刪除時將直接刪除設定資料集中的所有記錄。
例如, 刪除主鍵為1的blog下的所有entries:
b = Blog.objects.get(pk=1)
# Delete all the entries belonging to this Blog.
>>> Entry.objects.filter(blog=b).delete()
4.欄位查詢
exact、iexact
exact:精確匹配。區分大小寫
例如:
Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)
iexact:不區分大小寫的精確匹配
例如:
Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)
contains、icontains
contains:包含,大小寫敏感
例如:
Entry.objects.get(headline__contains='Lennon')
icontains:包含,大小寫不明感.
例如:
Entry.objects.get(headline__icontains='Lennon')
in
在一個給定的列表中.
Example:
Entry.objects.filter(id__in=[1, 3, 4])
gt、gte、lt、lte
gt:大於
例子:
Entry.objects.filter(id__gt=4)
Gte:大於或等於
Lt:小於
Lte:小於或等於
startswith、istartswith、endswith、iendswith
startswith:區分大小寫,開始位置匹配
例如:
Entry.objects.filter(headline__startswith='Will')
istartswith:不區分大小寫,開始位置匹配
endswith:區分大小寫,結束位置匹配
iendswith:不區分大小寫,結束位置匹配
range
範圍
例如:
import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))
等價SQL:
SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
year、month、day
year: 返回精確的年份
例如:
Entry.objects.filter(pub_date__year=2005)
等價SQL:
SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
month: 對於月份時間欄位,匹配一個整數從1 (January)到 12 (December).
day: 對於日期和日期時間欄位,具體到某一天的匹配。取一個整數的天數。
isnull
值為 True 或False, 相當於SQL語句IS NULL和IS NOT NULL.
例如:
Entry.objects.filter(pub_date__isnull=True)
等價SQL:
SELECT ... WHERE pub_date IS NULL;
5.常見聚合函式
Avg:
class Avg(expression, output_field=None, **extra)
返回給定expression 的平均值,其中expression必須為數值。
預設的別名:<field>__avg
返回型別:float
Count:
class Count(expression, distinct=False, **extra)
返回與expression 相關的物件的個數。
預設的別名:<field>__count
返回型別:int
有一個可選的引數:
distinct:
如果distinct=True,Count將只計算唯一的例項。它等同於COUNT(DISTINCT <field>) SQL語句。預設值為False。
Max:
class Max(expression, output_field=None, **extra)
返回expression 的最大值。
預設的別名:<field>__max
返回型別:與輸入欄位的型別相同,如果提供則為 output_field 型別
Min:
class Min(expression, output_field=None, **extra)
返回expression 的最小值。
預設的別名:<field>__min
返回的型別:與輸入欄位的型別相同,如果提供則為 output_field型別
StdDev:
class StdDev(expression, sample=False, **extra)
返回expression 的標準差。
預設的別名:<field>__stddev
返回型別:float
有一個可選的引數:
sample:
預設情況下,StdDev 返回群體的標準差。但是,如果sample=True,返回的值將是樣本的標準差。
Sum:
class Sum(expression, output_field=None, **extra)
計算expression 的所有值的和。
預設的別名:<field>__sum
返回型別:與輸入的欄位相同,如果提供則為output_field 的型別
Variance
class Variance(expression, sample=False, **extra)
返回expression 的方差。
預設的別名:<field>__variance
返回的型別:float
有一個可選的引數:
sample
預設情況下,Variance 返回群體的方差。但是,如果sample=True,返回的值將是樣本的方差。