QuerySet常规操作

示例演示
QuerySet常规操作
创建模型类

from django.db import models

class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()

def __str__ (self):   
    return self.name 

class Author(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()

def __str__ (self):  
    return self.name 

class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()

authors = models.ManyToManyField(Author) 
n_comments = models.IntegerField() 
n_pingbacks = models.IntegerField() 
rating = models.IntegerField() 

def __str__(self):  
    return self.headline 

常规操作

  1. QuerySet 创建对象的方法

from blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()

总之,一共有四种方法
From blog.models import Author

方法 1

Author.objects.create(name="Thompson", email="thompson@163.com")

方法 2

twz = Author(name=" Thompson", email=" thompson@163.com")
Python之:Django框架
奇酷学院高级讲师:郭建涛
twz.save()

方法 3

twz = Author()
twz.name=" Thompson"
twz.email=" thompson@163.com"
twz.save()

方法 4,首先尝试获取,不存在就创建,可以防止重复

Author.objects.get_or_create(name="WeizhongTu", email="tuweizhong@163.com")

返回值(object, True/False)

备注:前三种方法返回的都是对应的 object,最后一种方法返回的是一个元组,(object,
True/False),创建时返回 True, 已经存在时返回 False
当有一对多,多对一,或者多对多的关系的时候,先把相关的对象查询出来

from blog.models import Entry
from datetime import *
entry = Entry()
entry.headline = 'headline'
entry.body_text = "body text"
entry.pub_date = datetime.now()
entry.mod_date = datetime.now()

entry.n_comments = 1
entry.n_pingbacks = 1
entry.rating = 1
entry.save()
entry.authors.add(author)
entry.save()

entry = Entry.objects.get(pk=1)
cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()

  1. 获取对象的方法

查询所有

Entry.objects.all()

切片操作,获取10个人,不支持负索引,切片可以节约内存,不支持负索引

Entry.objects.all()[:10]

get是用来获取一个对象,多个会报错

Author.objects.get(name="Thompson")
如果需要获取满足条件的多个人,就要用到filter
Python之:Django框架
奇酷学院高级讲师:郭建涛
Author.objects.filter(name="abc")
Author.objects.filter(name__iexact="abc")

名称中包含 "abc"的人

Author.objects.filter(name__contains="abc")

名称中包含 "abc",且abc不区分大小写

Author.objects.filter(name__icontains="abc")

Author.objects.filter(name__regex="^abc") # 正则表达式查询
Author.objects.filter(name__iregex="^abc")# 正则表达式不区分大小写

  1. 删除符合条件的结果
    得到满足条件的结果,然后 delete 就可以(危险操作,正式场合操作务必谨慎)

Author.objects.filter(name__contains="abc").delete() # 删除 名称中包含 "abc"的人

如果写成
people = Author.objects.filter(name__contains="abc")
people.delete()
效果也是一样的,Django实际只执行一条 SQL 语句。

  1. 更新某个内容
    (1) 批量更新,适用于 .all() .filter() .exclude() 等后面 (危险操作,务必谨慎)

名称中包含 "abc"的人 都改成 xxx

Author.objects.filter(name__contains="abc").update(name='xxx')
(2) 单个 object 更新,适合get(), get_or_create(), update_or_create() 等得到的 obj,
和新建很类似。

twz = Author.objects.get(name="Tom")
twz.name="Tom"
twz.email="Tom@163.com"
twz.save() # 最后不要忘了保存!!!

  1. QuerySet 是可迭代的,比如:

es = Entry.objects.all()
for e in es:
print(e.headline)
Entry.objects.all() 或者 es 就是 QuerySet 是查询所有的 Entry 条目。

  1. 检查 Entry 中是否有对象
     如果只是检查 Entry 中是否有对象
    Entry.objects.all().exists()
     QuerySet切片

Entry.objects.all()[:10] #取出10条,可以节省内存
 查询集的数量
Entry.objects.count()
 强行将 QuerySet 变成 列表
list(Entry.objects.all())

  1. QuerySet 查询结果排序
    作者按照名称排序

Author.objects.all().order_by('name')
Author.objects.all().order_by('-name') # 在 column name 前加一个负号,可以实现倒序

  1. QuerySet 支持链式查询

Author.objects.filter(name__contains="WeizhongTu").filter(email="tuweizhong@163.com")
Author.objects.filter(name__contains="Wei").exclude(email="tuweizhong@163.com")

找出名称含有abc, 但是排除年龄是23 岁的

Person.objects.filter(name__contains="abc").exclude(age=23)
QuerySet进阶操作
创建模型类
from django.db import models

class Author(models.Model):
name = models.CharField(max_length=50)

qq = models.CharField(max_length=10) 
addr = models.TextField() 
email = models.EmailField() 

def __str__(self): 
    return self.name 

class Article(models.Model):
title = models.CharField(max_length=50)
author = models.ForeignKey(Author)
content = models.TextField()
score = models.IntegerField() # 文章的打分
tags = models.ManyToManyField('Tag')

def __str__(self): 
    return self.title 

class Tag(models.Model):
name = models.CharField(max_length=50)

def __str__(self): 
    return self.name 

比较简单,假设一篇文章只有一个作者(Author),一个作者可以有多篇文章(Article),一篇
文章可以有多个标签(Tag)。
values_list 获取元组形式结果
比如我们要获取作者的 name 和 qq
authors = Author.objects.values_list('name', 'qq')

使用list处理一下
list(authors)

如果只需要 1 个字段,可以指定 flat=True
Author.objects.values_list('name', flat=True)
values 获取字典形式的结果
比如我们要获取作者的 name 和 qq
Author.objects.values('name', 'qq')
list(Author.objects.values('name', 'qq'))
Article.objects.filter(author__name='twz915').values('title')

注意:

  1. values_list 和 values 返回的并不是真正的 列表 或 字典,也是 queryset,他们也是
    lazy evaluation 的(惰性评估,通俗地说,就是用的时候才真正的去数据库查)

  2. 如果查询后没有使用,在数据库更新后再使用,你发现得到在是新内容!!!如果想要旧
    内容保持着,数据库更新后不要变,可以 list 一下

  3. 如果只是遍历这些结果,没有必要 list 它们转成列表(浪费内存,数据量大的时候要更
    谨慎!!!)

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