QuerySet,查詢集,即從數據庫中查詢的到的集合。這一節主要學習與QuerySet相關的一些指令。
首先我們新建一個名爲learn_queryset的項目,在其中創建應用blog並修改settings(測試指令時需要使用)
修改blog/manage.py爲:
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete = models.CASCADE)
#從django1.9開始ForeignKey的on_delete參數就是必須的,如果沒寫會報錯
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.headline
8-1 新建對象
創建對象有以下幾種方法:
(1)Person.objects.create(name = 'name', age = age)
(2)p = Person(name = 'name', age = age)
p.save()
(3)p = Person(name = 'name')
p.age = age
p.save()
(4)Person.objects.get_or_create(name = 'name', age = age)
這種方法可以防止重複,它返回一個元組,第一個爲Person對象,第二個爲True或者False,沒有創建返回True,已經存在返回False。
8-2 獲取對象
(1)Person.objects.all()
獲取全部對象
(2)Person.objects.all()[ : 10]
獲取10個人,切片可以節約內存
切片不支持負索引,可以用reverse函數實現
Person.objects.all().reverse()[ : 2] 獲取最後兩個
(3)Person.objects.get(name = 'name')
獲取名爲name的一個對象(如果有兩個重名的對象會報錯)
get只能獲取一個對象,如果想獲取滿足條件的一些對象需要用filter
(4)Person.objects.filter(name = 'name')
名稱爲嚴格等於name的一些人
(5)Person.objects.filter(name__iexact = 'name')
名稱符合name但不區分大小寫
(6)Person.objects.filter(name__contains = 'name')
名稱中包含'name'的人
(7)Person.objects.filter(name__icontains = 'name')
名稱中包含'name'但不區分大小寫
(8)Person.objects.filter(name__regex = '^abc')
正則表達式查詢
(9)Person.objects.filter(name__iregex = '^abc')
正則表達式不區分大小寫
排除某些條件:
(QuerySet支持鏈式查詢)
(10)Person.objects.exclude(name__contains = 'name')
排除包含name的對象
(11)Person.objects.filter(name__contains = 'name').exclude(age = 23)
找出名稱含有name但年齡不是23歲的
8-3 刪除對象
使用函數delete()
(1)Person.objects.all().delete()
刪除全部數據
(2)Person.objects.get(name = 'name').delete()
刪除名爲name的對象
(3)Person.objects.filter(name__contains = 'name').delete()
刪除包含name的一些對象
8-4 去重
一般情況下QuerySet中不會出現重複,但當跨越多張表進行檢索後合併到一起就可能會出現重複,可以使用distinct函數去重
qs = qs.distinct()
8-5 更新
(1)批量更新
Person.objects.filter(name__contains = 'abc').update(name = 'xxx') #名稱中包含abc的都改成xxx
(2)單個更新,適用於get(),get_or_create(),update_or_create()等得到的obj
p = Author.objects.get(name = 'Youzhu')
p.name = 'Zhoumujing'
p.email = '[email protected]'
p.save() # !!一定要記得保存
8-6 迭代
QuerySet是可迭代的
es = Entry.objects.all()
for e in es:
print(e.headline)
8-7 排序
將查詢結果排序:
Author.objects.all( ).order_by('name')
Author.objects.all( ).order_by('-name') #在前面加上負號就可實現倒序排序
8-8 QuerySet可以用pickle序列化到硬盤再讀取出來
(這裏沒太懂……)
>>> import pickle
>>> query = pickle.loads(s) # Assuming 's' is the pickled string.
>>> qs = MyModel.objects.all()
>>> qs.query = query # Restore the original 'query'.
8-9 其他注意事項
(1)如果只是檢查Entry中是否有對象,應該用exists( )函數
Entry.objects.all( ).exists( )
(2)用len(es)可以得到Entry的數量,查詢數量推薦使用Entry.objects.count( )
(3)list(es)可以將QuerySet強行變成列表
教程鏈接:Django QuerySet API