making queries

title: Making Queries date: 2017-07-24 17:48:54 tags:

  • Python

  • Django

  • Making queries

    categories:

  • Python

示例模型

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

CRUD

更新ForeignKey字段和ManyToManyField字段

更新ForeignKey字段和更新普通字段一样,只需要把一个对象赋值给该字段即可。

更新ManyToManyField字段有所不同,需要使用add()方法想关系中添加记录。

一次向ManyToManyField字段添加多个字段,可以这样做:

检索对象

从数据库中检索对象,会在你的模型上通过Manager构造一个QuerySet

一个QuerySet代表数据库对象的集合。可以有零个、一个或者多个filters

可以通过模型的Manager获取QuerySet。每个模型至少有一个Manager,默认叫做objects

Manager只能通过模型类访问,而不是示例对象。

检索所有对象

使用filters检索特定的对象

提取QuerySet最常用的两个方法:

  • filter(**kwargs) : 返回一个包含符合查找参数的QuerySet

  • exclude(**kwargs) : 返回一个包含不符合查找参数的QuerySet

比如,要获取2006年的博客:

链式过滤

提炼一个QuerySet的结果是他自身,所以可以使用链式过滤的方法,来处理QuerySet

上例,把数据库中所有Entry作为初始QuerySet,添加一个filter,然后是一个exclusion,然后是另一个filter。最终的结果是满足下面这些条件的所有EntryQuerySet

  • headlineWhat开头

  • 发表时间介于2005-1-30今日之间

使用get()检索单个元素

限定QuerySet

LIMIT

OFFSET

不支持负数索引。

查找Field

基本的关键词查找参数形如 field__lookuptype=value,比如:

大致转换成SQL语句是:

Field Lookups

使用Q对象进行复杂查找

OR

对应SQL

~

Q对象必须要在查找关键词之前

合法:

不合法:

跨关系查找

跨关系查找(Lookups that span relationships)

查找所有名字为Beatles Blog的Blog的Entry对象

查找所有 至少有一个 headline包含Lennon的Entry对象 的Blog对象

如果跨关系过滤对象, 并且中间模型不存在满足过滤条件的值, 那么Django会把该中间模型当作空(所有值为NULL), 但是是合法的, 也就是说不会抛出异常.例如:

在这个查询中, 如果没有author和entry关联, 这将会被当作name属性没有被赋值处理, 而不会因为没有author对象而抛出异常.

那如果想要查询作者名称为空的Blog对象怎么办哪, 答案是可以使用isnull:

这将返回这样的Blog对象: author的name为空, 并且有一个空author的entry.

如果不想要空的author的entry对象, 可以使用:

获取指定数量

前n个

Entry.objects.all()[:5]

m至n个

Entry.objects.all()[5:10]

注意

  • 负数索引不支持, 比如: Entry.objects.all()[-1]

ManyToManyField

按照数量过滤

最后更新于

这有帮助吗?