python Django QuerySet API
python Django QuerySet API
一、模型.objects
这个对象是djangp.db.models.manager.Manager
的对象,这个类是一个空壳类,
他上面的所有方法是从 QuerySet
这个类上面拷贝过来的。
因此我们只要学会了QuerySet
,这个 objects
也就知道该如何使用了
示例代码一
from django.db.models.manager import Manager
Manager:class Manager(BaseManager.from_queryset(QuerySet)):
pass
@classmethod
def from_queryset(cls, queryset_class, class_name=None):
# queryset_class = QuerySet
if class_name is None:
class_name = '%sFrom%s' % (cls.__name__, queryset_class.__name__)
# class_name = '%sFrom%s' = "BaseManagerFromQuerySet"
return type(class_name, (cls,),
# return type(class_name, (cls,),class_dict)
# type动态的时候创建类
# 第一个参数是用来指定创建的类的名字,创建类名是:BaseManagerFromQuerySet
# 第二个参数是用来指定这个类的父类
# (cls,):元组,cls多继承,单继承后面加逗号
{'_queryset_class': queryset_class,
# class_dict = {'_queryser_class' : QuerySet }
**cls._get_queryset_methods(queryset_class),
# class_dict.update(cls._get_queryset_methods(Queryset)
# 第三个参数是用来指定这个类的一些属性和方法
# "**": 字典函数形参,关键字参数,多个属性和方法
# _get_queryset_methods 见下面代码
示例代码二
**cls._get_queryset_methods(queryset_class)
# _get_queryset_methods:这个方法就是将QuerySet中的一些方法拷贝出来
_get_queryset_methods
@classmethod
def _get_queryset_methods(cls, queryset_class):
...
# 定义函数
new_methods = {}
for name, method in inspect.getmembers(queryset_class, predicate=inspect.isfunction):
# predicate:过滤值
# isfunction:获取类中的行数,不获取属性
# predicate=inspect.isfunction
...
new_methods[name] = create_method(name, method)
return new_methods
二、返回新的QuerySet的方法
在使用 QuerySet
进行查找操作的时候,可以提供多种操作。比如过滤完后还要根据某个字段进行排序,那么这一系列的操作我们可以通过一个非常流畅的 链式调用
的方式进行。比如要从文章表中获取标题为 123 ,并且提取后要将结果根据发布的时间进行排序
示例代码如下:
articles = Article.objects.filter(title='123').order_by('create_time')
可以看到 order_by 方法是直接在 filter 执行后调用的。这说明 filter 返回的对象是一个拥有 order_by 方法的对象。而这个对象正是一个新的 QuerySet 对象。因此可以使用 order_by 方法。
1. filter:将满足条件的数据提取出来
返回一个新的 QuerySet 。具体的 filter 可以提供什么条件查询。请见查询操作章节。
2. exclude:排除满足条件的数据
返回一个新的 QuerySet
示例代码如下:
Article.objects.exclude(title__contains='hello')
以上代码的意思是提取那些标题不包含 hello 的图书
3. annotate:添加一个使用查询表达式
给 QuerySet 中的每个对象都添加一个使用查询表达式(聚合函数、F表达式、Q 表达式、Func表达式等)的新字段。
示例代码如下:
articles = Article.objects.annotate(author_name=F("author name"))
以上代码将在每个对象中都添加一个 author__name
的字段,用来显示这个文章的作者的年龄
4. order_by:指定将查询的结果根据某个字段进行排序
如果要倒叙排序,那么可以在这个字段的前面加一个负号
示例代码如下:
# 根据创建的时间正序排序
articles = Article.objects.order_by("create_time")
# 根据创建的时间倒序排序
articles = Article.objects.order_by("-create_time")
# 根据作者的名字进行排序
articles = Article.objects.order_by("author name")
# 首先根据创建的时间进行排序,如果时间相同,则根据作者的名字进行排序
articles = Article.objects.order_by("create_time",'author name')
一定要注意的一点是,多个 order_by ,会把前面排序的规则给打乱,而使用后面的排序方式
示例代码如下:
articles = Article.objects.order_by("create_time").order_by("author name")
他会根据作者的名字进行排序,而不是使用文章的创建时间
5. values:提取数据字段
默认情况下会把表中所有的字段全部都提取出来,可以使用 values 来进行指定,并且使用了 values 方法后,提取出
的 QuerySet 中的数据类型不是模型,而是在 values 方法中指定的字段和值形成的字典。
示例代码如下:
articles = Article.objects.values("title",'content')
for article in articles:
print(article)
以上打印出来的 article 是类似于 {“title”:“abc”,“content”:“xxx”} 的形式。
如果在 values 中没有传递任何参数,那么将会返回这个模型中所有的属性。