对查询集排序和查询集的字段查找条件输入

对查询到的结果排序

方式1:使用order_by方法

  • 根据模型本身的字段排序
    Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
    #排序规则是两个,它的排序意思是先按照pub_date排序,如果pub_date有相同的记录,就按照headline来排序这些相同的记录
    
    #上面的结果将按照pub_date 降序排序,然后再按照headline 升序排序。
    #"-pub_date" 前面的负号表示降序排序。隐式的是升序排序。
  • 若要随机排序,请使用"?",像这样:

    Entry.objects.order_by('?')

  • 如果想要根据关联的别的模型字段进行排序
    使用字段的名称后面跟上两个下划线(__),再跟上新模型中的字段的名称,直至你希望连接的模型。
    例:

    比如你有一个模型Entry,里面有一个外键字段blog关联到Blog模型类,你想在查询Entry的时候按照Blog下的name排序

    Entry.objects.order_by('blog__name')
    --根据别的模型字段排序的时候,如果没有指定字段,则采用默认的元类设置的排序规则
    --如果关联的模型也没有设置元类排序规则,那么就会根据关联的模型主键进行排序
    例:
    如果Blog模型类设置了默认的排序规则ordering=["name"]
    那么上面的排序可以写成下面这样
    Entry.objects.order_by('blog') 因为元类设置了默认的name排序,所以你指定按照Blog模型排序就是采用默认元类设置的方式
    如果元类没有设置ordering=["name"]
    那么Entry.objects.order_by('blog')默认是按照Blog模型类的主键id进行排序的,等同于Entry.objects.order_by('blog__id')
    所以如果元类设置的排序规则和你想要的规则不符合,或者根本没有设置元类排序规则,
    那么就应该像Entry.objects.order_by('blog__name')这样指定排序字段

方式2:定义默认的排序方式

在创建模型类的时候在元类选项里面加入排序规则
    class Meta:
        ordering = ["horn_length"]

对排序好的结果设置升序还是降序规则

调用asc()或者desc()方法

Entry.objects.order_by(Coalesce('summary', 'headline').desc())   最后会降序排序
Coalesce方法返回不为空的字段,可以理解为如果summary字段存在,就按照summary字段排序
如果summary字段不存在,就按照headline排序

判断返回查询集是否是排序过的查询集

使用ordered方法

如果QuerySet 是排好序的则返回True ,否则返回False

查询实例方法之filter方法,返回实例集合

返回一个新的QuerySet,包含与给定的查询参数匹配的对象。

查找的参数(**kwargs)应该满足本文字段查找中写的格式。在底层的SQL 语句中,多个参数通过AND 连接。

如果要使用复杂的查询,比如or查询,需要使用Q对象

查询实例中的字段方法返回字段值集合

values方法可以获取number字段的字典列表。

values_list可以获取number的元组列表。

values_list方法加个参数flat=True可以获取number的值列表。

class Building(models.Model):
    corporation = models.ForeignKey('company.Corporation', verbose_name=u'学校', related_name='buildings')
    number = models.CharField(u'楼栋编号', max_length=10, unique=True, db_index=True)
    create_time = models.DateTimeField(u'创建时间', auto_now_add=True)
In [1]: from apps.dormitory.models import Building
 
In [2]: buildings = Building.objects.values('number')
 
In [3]: buildings
Out[3]: [{'number': u'1'}, {'number': u'2'}, {'number': u'3'}, {'number': u'4'}, {'number': u'5'}]
 
In [4]: buildings_ = Building.objects.values_list('number')
 
In [5]: buildings_
Out[5]: [(u'1',), (u'2',), (u'3',), (u'4',), (u'5',)]
 
In [6]: buildings_list = Building.objects.values_list('number', flat=True)
 
In [7]: buildings_list
Out[7]: [u'1', u'2', u'3', u'4', u'5']

字段查找

字段查找里面写的方法适用于filter(),exclude(),get()方法

  • exact 精确匹配

    Examples:
    Entry.objects.get(id__exact=14)
    Entry.objects.get(id__exact=None)

    SQL equivalents:
    SELECT ... WHERE id = 14;
    SELECT ... WHERE id IS NULL;

  • iexact不区分大小写的精确匹配

    Example:
    Blog.objects.get(name__iexact='beatles blog')
    Blog.objects.get(name__iexact=None)
    SQL equivalents:
    SELECT ... WHERE name ILIKE 'beatles blog';
    SELECT ... WHERE name IS NULL;

    请注意,第一个查询将匹配 'Beatles Blog', 'beatles blog', 'BeAtLes BLoG'

  • contains 区分大小写的包含匹配

    Example:
    Entry.objects.get(headline__contains='Lennon')
    SQL equivalent:
    SELECT ... WHERE headline LIKE '%Lennon%';
    'Lennon honored today'会被匹配,但'lennon honored today'.不会被匹配
    在mysql数据库中%匹配任意个任意字符,_匹配一个任意字符

  • icontains 不区分大小的包含匹配

    Example:
    Entry.objects.get(headline__icontains='Lennon')
    SQL equivalent:
    SELECT ... WHERE headline ILIKE '%Lennon%';

  • in 在...范围内,不连续的范围查询,下面的range是连续的范围查询

    -- id 数字匹配
    Example:
    Entry.objects.filter(id__in=[1, 3, 4])
    SQL equivalent:
    SELECT ... WHERE id IN (1, 3, 4);

    范围不只可以是id这些文字值,也可以是实例组成的集合,

    -- 实例对象匹配
    下面的示例是找出所有关联了(Blog模型中的name包含Cheddar的实例)的所有Entry实例
    Example:
    inner_qs = Blog.objects.filter(name__contains='Cheddar') #首先查询出所有的Blog模型中的name包含Cheddar的实例
    entries = Entry.objects.filter(blog__in=inner_qs) #在查询Entry实例中存在于上面的范围的实例
    SQL equivalent:
    blog_obj_set = SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
    entries = select * from Entry where blog in blog_obj_set

    -- 字符串值匹配 values方法在本文中也有讲解,请在本页面搜索values
    inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
    entries = Entry.objects.filter(blog__name__in=inner_qs) # blog__name是外键模型之间使用其他模型的字段值,在本文使用其他模型字段排序中也有讲解

  • gt 大于

    Example:
    Entry.objects.filter(id__gt=4)
    SQL equivalent:
    SELECT ... WHERE id > 4;

  • gte 大于等于

  • lt 小于

  • lte 小于等于

  • startswith 开始位置匹配,区分大小写

    Example:
    Entry.objects.filter(headline__startswith='Will')
    SQL equivalent:
    SELECT ... WHERE headline LIKE 'Will%';
    SQLite 不支持区分大小写 LIKE 语句; Sqlite 下startswith 等于 istartswith .

  • istartswith 开始位置匹配,不区分大小写

    Example:
    Entry.objects.filter(headline__istartswith='will')
    SQL equivalent:
    SELECT ... WHERE headline ILIKE 'Will%';

  • endswith 结束位置匹配,区分大小写

    Example:
    Entry.objects.filter(headline__endswith='cats')
    SQL equivalent:
    SELECT ... WHERE headline LIKE '%cats';
    SQLite不支持区分大小写的LIKE语句;endswith用作SQLite的iendswith。

  • iendswith 结束位置匹配,不区分大小写

    Example:
    Entry.objects.filter(headline__iendswith='will')
    SQL equivalent:
    SELECT ... WHERE headline ILIKE '%will'

  • range 范围查询,连续的范围,in是不连续的范围

    Example:
    import datetime
    start_date = datetime.date(2005, 1, 1)
    end_date = datetime.date(2005, 3, 31)
    Entry.objects.filter(pub_date__range=(start_date, end_date))
    SQL equivalent:
    SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
    过滤具有日期的DateTimeField不会包含最后一天的项目,因为边界被解释为“给定日期的0am”。如果pub_date是DateTimeField,上面的表达式将变成这个SQL:
    SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';

  • year 对于日期DateField和日期时间DateTimeField字段确切的年匹配,整数年

    Example:
    Entry.objects.filter(pub_date__year=2005)
    SQL equivalent:
    SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
    当USE_TZ为True UTC时间,在过滤之前,datetime字段将转换为当前时区。

  • month 对于日期DateField和日期时间DateTimeField字段确切的月匹配,取整数1(1月)至12(12月)。

    Example:
    Entry.objects.filter(pub_date__month=12)
    SQL equivalent:
    SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
    当USE_TZ为True时,在过滤之前,datetime字段将转换为当前时区。

  • day 对于日期和日期时间字段,具体到某一天的匹配。取一个整数的天数

    Example:
    Entry.objects.filter(pub_date__day=3)
    SQL equivalent:
    SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
    EXTRACT() 函数用于返回日期/时间的单独部分,比如年、月、日、小时、分钟等等。

  • week_day 对于日期和日期时间字段,“星期几”匹配

    Example:
    Entry.objects.filter(pub_date__week_day=2)
    注意有的数据库星期几是从0开始的有的是从1开始的,所以使用这个方法前先查看数据库是从几开始索引的

  • hour 对于日期时间字段,精确的小时匹配。取0和23之间的整数。

    Example:
    Event.objects.filter(timestamp__hour=23)
    SQL equivalent:
    SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';

  • minute 对于日期时间字段,精确的分钟匹配。取0和59之间的整数。

    Example:
    Event.objects.filter(timestamp__minute=29)
    SQL equivalent:
    SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';

  • second 对于日期时间字段,精确的秒匹配。取0和59之间的整数。

    Example:
    Event.objects.filter(timestamp__second=31)
    SQL equivalent:
    SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';

  • isnull 值为 True 或 False, 相当于 SQL语句IS NULL和IS NOT NULL.

    Example:
    Entry.objects.filter(pub_date__isnull=True)
    SQL equivalent:
    SELECT ... WHERE pub_date IS NULL;

  • search 一个Boolean类型的全文搜索,以全文搜索的优势。这个很像 contains,但更快

    Example:
    Entry.objects.filter(headline__search="+Django -jazz Python")
    SQL equivalent:
    SELECT ... WHERE MATCH(tablename, headline) AGAINST (+Django -jazz Python IN BOOLEAN MODE);
    注意,这仅在MySQL中可用,并且需要直接操作数据库以添加全文索引。默认情况下,Django使用BOOLEAN MODE进行全文搜索

  • regex 区分大小写的正则表达式匹配。

    Example:
    Entry.objects.get(title__regex=r'^(An?|The) +')
    SQL equivalents:
    SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
    SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'c'); -- Oracle
    SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
    SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite
    建议使用原始字符串(例如,r'foo'而不是'foo')来传递正则表达式语法。(即带上前面的字母r)

  • iregex 不区分大小写的正则表达式匹配。

    Example:
    Entry.objects.get(title__iregex=r'^(an?|the) +')
    SQL equivalents:
    SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
    SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle
    SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL
    SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容