Django 2.2 新特性清單

長江CJ發表於2019-04-26

原文件地址:docs.djangoproject.com/en/2.2/rele…

最主要feature:Model Conatrains

可以在 model 的 Meta 中定義一個 constrains 列表。比如下面這個例子,新增了一個age欄位資料必須大於等於18的限制。

注意:不能在 AbstractModel 類裡面定義constrains,因為每個 constrain都必須要有一個唯一的名字。如果在AbstractModel中定義的話,勢必會重複。

from django.db import models

class Customer(models.Model):
    age = models.IntegerField()

    class Meta:
        constraints = [
            models.CheckConstraint(check=models.Q(age__gte=18), name='age_gte_18'),
        ]
複製程式碼

知識點回顧:models.Q 查詢

models.Q 可以用來組合產生複雜的查詢語句,比如 OR 查詢:

queryset = User.objects.filter(
    Q(first_name__startswith='R') | Q(last_name__startswith='D')
)
複製程式碼

AND 查詢:

queryset = User.objects.filter(
    Q(first_name__startswith='R') & Q(last_name__startswith='D')
)
複製程式碼

first_name‘R’開頭, 但是 last_name 不以Z開頭:

 queryset = User.objects.filter(
    Q(first_name__startswith='R') & ~Q(last_name__startswith='Z')
)
複製程式碼

詳情情見:

class CheckConstraint

check

必填引數。

需要傳入一個Q 物件,表明你需要怎樣的 constrain 要求,比如CheckConstraint(check=Q(age__gte=18), name='age_gte_18')確保age欄位用於不會小於18.

name

必填引數。必須是唯一的。

class UniqueConstraint

fields

對哪些 fields 做唯一限制。比如UniqueConstraint(fields=['room', 'date'], name='unique_booking')確保每個 room 一天只能被預訂一次。

name

同上,必須是唯一的。

condition

滿足什麼條件時才要求強制 constrain 條件。

測試用例:

Django 2.2 新特性清單

Django 2.2 新特性清單

model 相關

automatic transaction的變化

2.2釋出日誌裡面一個不起眼的地方寫了這樣一句:

Django no longer always starts a transaction when a single query is being performed, such as Model.save(), QuerySet.update(), and Model.delete(). This improves the performance of autocommit by reducing the number of database round trips.

也就是說 django 不再和之前一樣,每個 query(比如 save,update,delete) 都會開啟一個 transaction。這樣可以通過減少 django <-> 資料庫往返次數來提高效率。

Index.condition

文件

考慮到這樣的應用場景:table 很大,但是 query 只會查詢一小部分的資料。為所有資料項都建一個索引是沒必要的,這時候就可以針對某一部分特定資料建立索引。

比如下面這個例子:

indexes = [
    models.Index(
        fields=['username'],
        condition=models.Q(age__gte=30),
        name='idx_username_age_gte30'
    )
]
複製程式碼

將只會為年齡大於30歲的使用者在username這個欄位上建立索引。

Index.condition 底層支援依賴於資料庫的partial indexes。 而MySQL、MariaDB、Oracle都不支援partial indexes,所以這些資料庫會直接忽略掉。

bulk_create

增加了一個ignore_conflicts引數,設定為 TRUE 的時候告訴資料庫忽略由於 constrain 產生的錯誤。

bulk_update

bulk_update(objs, fields, batch_size=None)

需要 update 大量資料的時候很有用。

>>> objs = [
...    Entry.objects.create(headline='Entry 1'),
...    Entry.objects.create(headline='Entry 2'),
... ]
>>> objs[0].headline = 'This is entry 1'
>>> objs[1].headline = 'This is entry 2'
>>> Entry.objects.bulk_update(objs, ['headline'])
複製程式碼

這樣會比使用一個 for 迴圈一個一個呼叫update()方法速度更快。

有幾點需要注意:

  • save()方法不會被呼叫,所以post_savepre_save訊號將不會觸發。
  • 如果資料量很大,可以指定batch_szie 引數

migrations

新增了一個--plan命令列引數,用來檢視 django 將要執行什麼資料庫修改操作。

Django 2.2 新特性清單

針對 PG 資料庫的優化

django.contrib.postgres

  • ordering引數增加了ArrayAggStringAgg。可以針對 aggv 資料來做排序。
  • 新增的BTreeIndex, HashIndexSpGistIndex 類允許建立 B-Tree, hash, and SP-GiST 索引。
  • BrinIndex現在有了一個autosummarize引數。
  • SearchQuerysearch_type做了些變化。

HttpRequest

新增了HttpRequest.headers,以便更方便地獲取請求頭資訊。

>>> request.headers
{'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6', ...}

>>> 'User-Agent' in request.headers
True
>>> 'user-agent' in request.headers
True

>>> request.headers['User-Agent']
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers['user-agent']
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

>>> request.headers.get('User-Agent')
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers.get('user-agent')
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
複製程式碼

之前需要通過 request.META獲取,相對要麻煩了很多。在2.2之前的版本,如果你想要獲取所有的 HTTP 請求頭的話,可以這麼獲取:

import re
regex = re.compile('^HTTP_')
dict((regex.sub('', header), value) for (header, value) 
       in request.META.items() if header.startswith('HTTP_'))
複製程式碼

其他特性

其他瑣碎的東西還有很多,比如:

  • collectstatic --ignore PATTERN選項,忽略指定模式的靜態資源。
  • inspectdb有了更豐富的功能。
  • Tests 新功能。

詳細的,還是去看官方的文件吧。此外還提到了一些往前不相容的改變,如果你的專案裡面用到了,也需要注意注意。

Django 2.2 新特性清單

我的公眾號:全棧不存在的

Django 2.2 新特性清單

相關文章