79.經常使用的返回QuerySet對象的方法使用詳解: filter, exclude,annotate

返回新的QuerySet的經常使用方法:

1.filter: 將知足條件的數據提取出來,返回一個新的QuerySet

如下所使用的模型article,category,定義模型models.py文件中,示例代碼爲:
from django.db import models


class Category(models.Model):
    name = models.CharField(max_length=100)

    class Meta:
        db_table = 'category'


class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    category = models.ForeignKey('Category', on_delete=models.CASCADE, null=True)
    create_time = models.DateTimeField(auto_now_add=True, null=True)

    def __str__(self):
        return "<(Article: id: %s,title: %s, content: %s)>" % (self.id, self.title, self.content)

    class Meta:
        db_table = 'article'
(1). 在使用QuerySet進行查找的時候,能夠執行多種操做好比filter()方法進行id的過濾完成後,還要根據某個字段進行排序,那麼這一系列的操做咱們能夠經過一個很是專業的操做叫作「鏈式調用」的方式進行。好比,要從文章列表中獲取id大於等於2的,而且提取以後將結果根據發佈的時間進行排序(order_by()),示例代碼以下:
首先查看數據庫表中數據的信息:

在這裏插入圖片描述

from django.http import HttpResponse
from .models import Article
from django.db.models.manager import Manager
from django.db.models.query import QuerySet


def index4(request):
    articles = Article.objects.filter(id__gte=2).order_by("create_time")
    for article in articles:
        print("%s, %s, %s" % (article.title, article.content, article.create_time))
    print(articles.query)
    return HttpResponse("success !")
打印出結果以下:

3, 鋼鐵是怎樣煉成的, 你好, 2020-02-05 03:03:30.860556+00:00
2, Hello World, 你們好, 2020-02-05 03:04:59.860556+00:00
4, 中國吸引力, 精彩極了, 2020-02-05 03:04:59.860556+00:00python

由輸出的結果,咱們能夠看出文章已經按時間的順序進行排序了,默認狀況下是按照降序的順序。sql

打印出django底層所執行的原生SQL語句:

SELECT article.id, article.title, article.content, article.category_id, article.create_time FROM article WHERE article.id >= 2 ORDER BY article.create_time ASC。
能夠看出咱們的查詢條件已經被翻譯成了WHERE article.id >= 2 ORDER BY article.create_time ASC數據庫

(2). 若是想要將id大於等於3,可是不等於4的文章查找出來,就可使用Q表達式和~來實現。注意:必定不要用"xxx != xxx"來實現,由於這樣在python中會返回bool型的True或者是False。示例代碼以下:
from django.db.models import Q
from django.http import HttpResponse
from .models import Article, Category
from django.db.models.query import QuerySet
from django.db.models.manager import Manager


def index5(request):
    articles = Article.objects.filter(id__gte=3).filter(~Q(id=4))
    # articles = Article.objects.filter(id__gte=3).exclude(id=4)
    for article in articles:
        print("%s, %s, %s" % (article.id, article.title, article.create_time))
    print(articles.query)
    return HttpResponse('success!')
打印出執行的結果:

3, 鋼鐵是怎樣煉成的, 2020-02-05 03:03:30.860556+00:00django

執行的sql語句爲:SELECT article.id, article.title, article.content, article.category_id, article.create_time FROM article WHERE (article.id >= 3 AND NOT (article.id = 4))函數

2. exclude:排除知足條件的數據,返回一個新的QuerySet。示例代碼以下:

def index5(request):
    articles = Article.objects.exclude(title__icontains='hello')
    for article in articles:
        print("%s, %s, %s" % (article.id, article.title, article.create_time))
    print(articles.query)
    return HttpResponse('success!')
打印出結果以下所示:

3, 鋼鐵是怎樣煉成的, 2020-02-05 03:03:30.860556+00:00
4, 中國吸引力, 2020-02-05 03:04:59.860556+00:00翻譯

django底層執行的sql語句:SELECT article.id, article.title, article.content, article.category_id, article.create_time FROM article WHERE NOT (article.title LIKE %hello%)code

3. annotate:給QuerySet中的每一個對象都添加一個使用查詢表達式(聚合函數,F表達式,Q表達式,Func表達式等)的字段,示例代碼以下:

def index5(request):
    articles = Article.objects.annotate(category_name=F("category__name"))
    for article in articles:
        print("%s, %s, %s" % (article.id, article.title, article.category_name))
    print(articles.query)
    return HttpResponse('success!')
打印出返回的結果以下:

1, Hello, 最新文章對象

2, Hello World, 最熱文章
3, 鋼鐵是怎樣煉成的, 高評分文章
4, 中國吸引力, 高評分文章blog

SELECT article.id, article.title, article.content, article.category_id, article.create_time, category.name AS category_name FROM article LEFT OUTER JOIN category ON (article.category_id = category.id)排序

相關文章
相關標籤/搜索