django QuerySet裏那些經常使用又不常見的技巧

最近的做業是django rest,業務有點複雜,所以model部分會有各類查詢,有些確實以前不多 用到的東西,向Q,F,這都是毛啊git

QuerySet

像Entry.Objects.all(),這些操做返回的是一個QuerySet對象,這個對象 比較特別,並非執行Objects.all(),或者filter以後就會與數據庫交互, 具體參看官方文檔,與數據庫交互的狀況:sql

https://docs.djangoproject.com/en/dev/ref/models/querysets/數據庫

Internally, a QuerySet can be constructed, filtered, sliced, and generally passed around without actually hitting the database. No database activity actually occurs until you do something to evaluate the queryset.

能夠print queryset對象的query屬性查看具體sql

1. list(Entry.Objects.all())
2. for e in Entry.Objects.all():pass  
# 便利第一個元素的時候會觸發數據庫操做
3. Entry.Objects.all()[2:10] 
# 這種狀況不會返回全部元素,sql中會加上limit的,分頁能夠利用這一點

Q和F

F class

from django.db.models import F

Instances of F() act as a reference to a model field within a query. These references can then be used in query filters to compare the values of two different fields on the same model instance.

這就是說F是專門取對象中某列值的,例子: 'QuerySet 判斷一個model兩個字段是否相等'django

Q class

from django.db.models import Q

Keyword argument queries – in filter(), etc. – are 「AND」ed together. If you need to execute more complex queries (for example, queries with OR statements), you can use Q objects.

從文檔把Q放在Complex lookups with Q objects,下就能夠看出,Q是作複雜查詢的app

and --> XX.objects.filter(Q(f=1),Q(f=2))  # 確定木有結果 f == 1 and f == 2
or --> XX.objects.filter(Q(f=1) | Q(f=2)) # f ==1 | f == 2
not --> XX.objects.filter(~Q(f=1),Q(f=2))  # f != 1 and f == 2

判斷某字段是否爲null

_tasks = tasks.exclude(group__isnull=True)

各類雙下滑線對應的各類方法,參看文檔 querysets field lookuplua

https://docs.djangoproject.com/en/1.6/ref/models/querysets/#field-lookups

QuerySet !=

例如model 有兩列 一列叫作user,一列叫作assigned_user, 需求是取出user!=1的記錄,django裏面不能使用!=,須要用Q.net

from django.db.models import Q
direct_comment = _tasks.filter(~Q(user=1))

Q還能夠這樣,user = 1或者2的元素rest

direct_comment = _tasks.filter(Q(user=1) | Q(user=2))

QuerySet 判斷一個model兩個字段是否相等

from django.db.models import F

例如model 有兩列 一列叫作user,一列叫作assigned_user,
需求是取出user=assigned_user的記錄

direct_comment = _tasks.filter(user=F('assigned_user'))

django group_by

對某些取到的QuerySet分組仍是很常見的code

def group_by(query_set, group_by):
    '''util:django 獲取分類列表'''
    assert isinstance(query_set, QuerySet)
    django_groups = query_set.values(group_by).annotate(Count(group_by))
    groups = []
    for dict_ in django_groups:
        groups.append(dict_.get(group_by))
    return groups

例如:
assign_to = _tasks.exclude(user=F('assigned_user'))
groups = group_by(assign_to, 'group')
取出的是一個列表groups = [1L, 3L, 4L]

更多幹貨

django issue對象

相關文章
相關標籤/搜索