Django学习笔记六(QuerySet)

QuerySet查询笔记

1. 创建对象

两种方法:

# 创建完必须调用save才保存
a = Blog(name='a', tagline='b')
a.save()

# 一个步骤创建和保存对象
b = Blog.object.create(name='a', tagline=b )

一对多和多对多需使用其他方法

2. 检索对象

通过一个Manager(系统默认创建,可以用Objects调用它)构建QuerySet,用以表示一个SELECT语句。

检索所有对象

# 使用Manager的all()方法,返回返回表中所有对象
all_entries = Entry.object.all()

使用过滤器检索特定对象

# filter过滤器,返回包含与给定查找参数匹配的新对象
Entry.objects.filter(pub_date__year=2006)
Entry.objects.all().filter(pub_date__year=2006)

# exclude过滤器,与filter相反,返回不包含给定参数查找匹配的新对象
Entry.objexts.exclude(pub_date__year=2006)

链接过滤器

# 这个QuerySet放回包含以“what"开头的所有条目,这些条目排除了今天,从2015年1月30日到昨天之间发布的条目。
Entry.object.filter(
		headline__startswith='what'
	).exclude(
		pub_date_gte=datetime,date.today()
	).filter(
		pub_date__gte=datetime.date(2015,1,30))

过滤的QuerySets是独一无二的

每当你精炼一个QuerySet,你就会得到一个全新的QuerySet,与以前没有任何关系QuerySet。每个细化都会创建一个QuerySet可以存储,使用和重用的独立且不同的细分。

# 这三者QuerySets是分开的。第一个是QuerySet包含所有条目的基础, 其中包含以“What”开头的标题。第二个是第一个的子集,其他标准排除了pub_date今天或将来的记录。第三个是第一个的子集,其他标准仅选择pub_date当前或未来的记录。initial QuerySet(q1)不受细化过程的影响。
q1 = Entry.objects.filter(headline__startswith="What")
q2 = q1.exclude(pub_date__gte=datetime.date.today())
q3 = q1.filter(pub_date__gte=datetime.date.today())

使用get()检索单个对象

# 当查询条件只有一个对象匹配时,可以使用get(),如果结果不为一个会报错
one_entry = Entry.objects.get(pk=1)

QuerySet切片

# 放回查询集合中每个第二个对象的列表,不支持负索引,相当于SQL中的limit和offset子句,禁止对切片查询进行进一步的过滤和排序,会产生模糊性,检索一个对象可以使用具体的[0]索引
Entry.objects.all()[:10:2]

Entry.objects.order_by('headline')[0]  # 相当于下面这一句
Entry.objects.order_by('headline')[0:1].get()

字段查找

字段查找是指定SQL WHERE子句的内容的方式。它们被指定为QuerySet 方法的关键字参数filter()exclude()或者 get()

基本查找关键字参数采用表单field__lookuptype=value。(这是一个双重下划线)。例如:

# 发布时间小于2006-01-01
Entry.objects.filter(pub_date__lte='2006-01-01')

# 查找中指定的字段必须是模型字段的名称。但是有一个例外,如果ForeignKey你可以指定后缀的字段名称_id。在这种情况下,value参数应包含外部模型主键的原始值。例如:
Entry.objects.filter(blog_id=4)

# 精确匹配 exact(),如果查询关键字参数不包含双下划线,则默认使用exact查找,一下2个语句等效
Entry.objects.get(headline__exact='Cat bites dog')
Entry.objects.get(headline='Cat bites dog')

# 使用iexact(),不区分大小写
Bolg.objects.get(name__iexact='beatles blog')

# 使用contains(不区分大小写的icontains )
Entry.objects.get(headline__contains='Lennon')
SELECT ... WHERE headline LIKE '%Lennon%';  # 翻译为sql

# startswith 和 endswith 分别表示以搜索开始和结束,还有不区分大小写的 istartswith 和 iendswith
Blog.objects.filter(headling__startswith='Lennon')
Blog.objects.filter(headling__endswith='dog')

跨越关系的查找

# 主外键自动Join,只需使用跨模型的相关字段的字段名称,如:
Entry.objects.filter(blog_name='Beatles Blog')

# 它也可以倒退。要引用“反向”关系,只需使用模型的小写名称。这个例子检索所有Blog具有至少一个对象Entry ,其headline包含'Lennon':
Blog.objects.filter(entry__headline__contains="Lenno")

主键查询

# 在查询中 pk=id=id__exact  如:
Blog.objects.get(pk=14);
Blog.objects.get(id__exact=14)
Blog.objects.get(id=14)

# 使用pk不仅限于__exact查询 - 可以组合任何查询术语以pk对模型的主键执行查询:
Blog.objects.filter(pk__in=[1,4,7])  # 博客条目id再[1,4,7]三者之间
Blog.objects.filter(pk__gt=14)  # 博客条目id大于14


使用Q对象进行查询

使用filter()进行查询,默认是用”AND“将多条语句编辑在一起,如果其他复杂的查询(带OR语句的查询),则可以使用Q()

from django.db.models import Q

# 此语句生成一个 Q 表示两个"question__startswith"查询的“OR”的对象:
Q(question__startswith="What") | Q(question__startswith='Who')

# Q 对象之间可以使用 & | ~ 进行链接,~表示否定
Q(question__startswith='Who') | ~Q(pub_date__year=2005)

# 每个查找函数,采用关键字参数(例如filter(), exclude(), get())也可以通过一个或多个 Q 对象作为位置参数。Q 对象必须位于任何关键字参数的定义之前。即question__startswith='Who',这种之前。
Polls.objects.get(Q(question__startswith="Who"), 
                  Q(pub_date=date(2005,5,2))|
                  Q(pub_date=date(2005, 5, 6))
                 )  # 这个语句中','相当于 AND,

删除对象

使用delete()方法,删除会遵守SQL约束的行为,如级联删除等

# 删除一个具体的对象
e.delete()

# 批量删除对象,可以使用QuerySet删除
Entry.objects.filter(pub_date__year=2005).delete()

# 删除整个表
Entry.objects.all().delete()

更新对象

# 批量更新对象
Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')

外键表访问主键表

# 使用外键属性访问主表并,可以对外键进行修改并保存
e = Entry.objects.get(id=2)
e.blog = same_blog
e.save

主键表向下访问外键表

# 如果模型具有a ForeignKey,默认情况下,这 Manager是命名的FOO_set,FOO源模型名称是小写的。此Manager返回 QuerySets,其可以被过滤和操纵与上述“检索对象”部分中描述。例如:
b = Blog.objects.get(id=1)
b.entry_set.all()  # 返回这条博客的所有记录
b.entry_set.filter(headline__contains='Lennon')

一切其他常用的方法

add(obj1, obj2, ...)  # 将特定的模型对象加入关联对象集合。

create(**kwargs)  # 创建一个新对象,保存它并将其放入相关的对象集中。返回新创建的对象。

remove(obj1, obj2, ...)  # 从相关对象集中删除指定的模型对象。

clear()  # 从相关对象集中删除所有对象。

set(objs)  # 替换相关对象集。

# 要分配相关集的成员,请将该set()方法与可迭代的对象实例一起使用。例如,if e1和e2是Entry 实例:
b = Blog.objects.get(id=1)
b.entry_set.set([e1, e2])

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=200)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
    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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值