本篇筆記目錄索引如下:
- model 準備
- 增
- 查
- 刪
- 改
1、model 準備
在上一篇筆記中,我們新建了一個 application,增加了幾個model 同步到了資料庫,這次我們新建一個名為 blog 的application,同步資料結構,
大概分為以下幾步:
- python3 manage.py startapp blog
- 將 'blog.apps.BlogConfig’, 寫入 settings.py INSTALLED_APPS
- 更新 blog/models.py
- python3 manage.py makemigrations blog
- python3 manage.py migrate blog
具體執行 migrate 的操作步驟,可以參見上一篇筆記,
blog/models.py 的具體內容如下:
# blog/models.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=200)
email = models.EmailField()
def __str__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
number_of_comments = models.IntegerField()
number_of_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self):
return self.headline
2、增
有以下幾種方法(以下操作皆在 python3 manage.py shell 環境中進行):
實體化,然后save() 保存
from blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()
當執行 save() 操作之后,資料就會創建到資料庫,因為主鍵 id 為自動增長的,所以id會自動賦值,
當然也可以先實體化一個空的 Blog,然后再賦值:
from blog.models import Blog
b = Blog()
b.name = 'hunter'
b.tagline = 'tag lines'
b.save()
save 之后,如果需要修改 name 的值,可以直接進行修改:
b.name = ‘python’
b.save()
使用 create() 方法創建
from blog.models import Blog
b = Blog.objects.create(name='hunter', tagline='tagline')
呼叫 create() 方法,會回傳這條資料保存后的物件,
批量創建
如果要批量創建資料,用上面的方法大概的就是在一個回圈里,挨個去實體化一個 Blog,然后執行 save() 操作,
但Django 提供了一個 bulk_create() 的方法,可以提高這個效率,使用示例如下:
from blog.models import Blog
blog_1 = Blog(name='hunter1', tagline='tagline1')
blog_2 = Blog(name='hunter2', tagline='tagline2')
blog_obj_list = [blog_1, blog_2]
Blog.objects.bulk(blog_obj_list)
3、查
查詢的語法有查詢之后回傳 QuerySet 的查詢,比如 filter(),exclude()
也有 回傳單個 object 的查詢,比如 get()
對于 QuerySet,這個我們可以簡單理解為是多個 object 實體形成的串列,但是這個串列是Django的一種特有的形式,具有能進行其他條件篩選的功能,
接下來簡單介紹一下查詢的功能:
filter(),過濾篩選,回傳的是符合條件的資料
比如我們要搜索 Entry 表里,name 的值為 hunter 的資料,使用如下:
Entry.objects.filter(name='hunter')
exclude(),排除篩選,回傳的是不符合條件的資料
比如我們要搜索 Entry 表里,name 的值不為 hunter 的資料:
Entry.objects.exclude(name='hunter')
鏈式查詢:
Django 支持 鏈式查詢,可以多個 filter 或者 exclude 條件累加,取的是 AND 的邏輯:
Entry.objects.filter(name='hunter').exclude(name='paul').filter(id=1)
懶加載:
Django 的查詢有一個機制叫做懶加載,意思是只有當你真正需要去取資料的時候
系統才會去資料庫獲取資料,官方例子如下:
>>> q = Entry.objects.filter(headline__startswith="What")
>>> q = q.filter(pub_date__lte=datetime.date.today())
>>> q = q.exclude(body_text__icontains="food")
>>> print(q)
上述陳述句雖然看起來查詢了三次資料庫,但實際上只有最后 print(q) 的時候才去訪問了資料庫,
get()
前面講的 filter 和 exclude 回傳的都是 QuerySet,簡單來說就是多個 object 形成的串列,而 get() 操作回傳的直接是一條符合條件的 object,
比如:
blog = Blog.objects.get(id=1)
注意: get() 方法需要慎用,因為查詢的條件在資料庫里,有多潭訓者一條都沒有的時候系統會報錯,
get() 的查詢一般僅用在我們能夠確定 在資料庫里有且僅有一條資料情況下,
對QuerySe進行切片
用 filter 對資料進行操作的時候,如果需要對資料的回傳數量進行限制,需要用到 python 里的切片,
PS:數量的回傳限制對應于 mysql 里的 limit 用法,
比如:
blog_list = Blog.objects.all()[1:5]
但是和 python 里的切片不一樣的時候,Django 的查詢不支持 負數查詢,比如下面的操作是不被允許的:
Blog.objects.all()[-1] # error
Blog.objects.all()[-1: 3] # error
欄位條件查找:
在我們使用 mysql 的時候 where 后面會跟一些查詢的限制條件,在Django 里用 雙下劃線來實作
比如 id 的值大于 5
Model.objects.filter(id__gt=5)
大于:gt
大于等于:gte
小于:lt
小于等于:lte
包含:in
是否為 null :isnull
精確查找:
精確查找使用 exact,一般查詢的時候 后面不加上面的欄位條件,都屬于精確查找,不過默認是將 exact 欄位省略,
比如,下面兩條代碼是一致的:
Blog.objects.get(id__exact=14)
Blog.objects.get(id=14)
查詢外鍵關聯資料
比如 Entry 這個 model 的外鍵是 Blog,我們想通過 查找 Blog 的 name 欄位為 Hunter 的Entry 資料:
Entry.objects.filter(blog__name='Hunter')
如果你想反向搜索也是可以的,將 model 名稱小寫即可:
Blog.objects.filter(entry__headline='abc')
計算查找
在Django 中參考欄位來進行比較,比如我們想實作如下功能:
select * from blog_entry where number_of_comments > number_of_pingbacks;
可以使用Django 中的 F,它的作用是 取值,取出其中的欄位值,那么上述例子可以用 Django來實作可以是:
from django.db.models import F
Entry.objects.filter(number_of_comments__gt=F(“number_of_pinbbacks"))
還可以在使用中對 F() 進行一系列的操作:
Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks') * 2)
Entry.objects.filter(rating__lt=F('number_of_comments') + F('number_of_pingbacks'))
pk 使用方法
pk 意思是 primary key ,主鍵,可以直接使用 pk 來搜索,但在專案中一般是使用 id 作為主鍵,所以一般是等價于id的用法:
Blog.objects.filter(pk__gt=11)
Q 查詢:
我們知道可以使用 filter 來進行 鏈式查詢,那個邏輯是一個且的邏輯,那么 或 的邏輯應該如何處理呢
我們可以使用Q() 來實作
我們可以使用 Q() 來將一個個的條件 串起來,比如,我們想篩選 Blog 中 id= 3 或者 id = 4 的資料可以使用如下:
Blog.objects.filter(Q(id=3) | Q(id=4))
也可以實作 且 的功能Q() & Q()
取反:~Q()
4、刪
如果要洗掉 objects,有兩種方法,一種先獲取 object,然后 delete()
blog = Blog.objects.get(id=1)
blog.delete()
或者通過 filter 來 批量洗掉:
Blog.objects.filter(id__gte=10).delete()
注意:如果有外鍵關聯了 Blog,且 on_delete關系設定為 models.CASCADE,
那么洗掉相應的 Blog 的時候,對應的 關聯的 Entry 資料也會被洗掉
5、改
批量更新:
Blog.objects.filter(id__gte=200).update(name='hunter')
單個更新:
blog = Blog.objects.get(id=1)
blog.name = ‘hunter’
blog.save()
以上就是我們這一篇筆記的全部內容,下一篇筆記將詳細介紹Django model里的 各個欄位型別以及欄位屬性值,
本文首發于本人微信公眾號:Django筆記,
原文鏈接:Django筆記三之使用model對資料庫進行增刪改查
如果想獲取更多相關文章,可掃碼關注閱讀:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/547378.html
標籤:其他
