zoukankan      html  css  js  c++  java
  • 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:00

    由输出的结果,我们可以看出文章已经按时间的顺序进行排序了,默认情况下是按照降序的顺序。

    打印出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:00

    执行的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%)

    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, 中国吸引力, 高评分文章

    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)

    始于才华,忠于颜值;每件事情在成功之前,看起来都是天方夜谭。一无所有,就是无所不能。
  • 相关阅读:
    dom解析和sax解析
    pull解析和sax解析的区别
    HashMap和HashTable的区别
    Java Socket通信原理简介
    Socket通信原理简介
    Android获取网络连接状态(3G/Wifi)及调用网络配置界面
    Android布局控件之LinearLayout
    onAttachedToWindow () 和 onDetachedFromWindow () ; 以及更新视图的函数ondraw() 和dispatchdraw()的区别
    Android开源界面库--ResideMenu用法
    iOS如何接收服务端返回的布尔值
  • 原文地址:https://www.cnblogs.com/guyan-2020/p/12267195.html
Copyright © 2011-2022 走看看