我们经常使用Model.objects.filter()等方法查询数据库,本文主要总结objects等知识。
创建一个模型类:
from django.db import models
class User(models.Model):
pass
当django框架启动的时候,会默认给User模型类创建一个objects类变量,是Manager类型,即模型管理器类, 一个模型类中至少有一个模型管理器类:
class Manager(BaseManager.from_queryset(QuerySet)):
pass
models.Manager类中没有实现具体的变量和方法,继承自django的基础管理器类:BaseManager,同时给BaseManager添加一个参数QuerySet类,BaseManager类会读取QuerySet类中的变量和方法,并添加给BaseManager自身使用,QuerySet类有filter()、get()、all()、create()等方法,因此可以使用Model.objects.filter()等方法查询数据库。
如果我们重写objects那么就可以添加或者重写一些数据库操作方法:
from django.db import models
# 定义用户模型管理器类,继承自django模型管理器类:Manager
class UserManager(models.Manager):
# 添加自定义方法
def find_self(self, **params)
pass
# 重写get方法
def get(self, **params)
pass
# 定义用户模型类
class User(models.Model):
# 指定用户模型管理器类
objects = UserManager()
# 使用
User.objects.find_self()
User.objects.get() # 重写后的get方法
也可以在UserManager中重写get、filter、all等方法,但是pycharm开发工具不会提示重写get方法的标记,因为BaseManager类读取QuerySet类中的变量和方法,并不是继承关系,django源码中BaseManager类会继承一个动态创建的类BaseManagerFromQuerySet,BaseManagerFromQuerySet复制了QuerySet类的部分方法和变量。
User.objects.get() # 调用重写后的get方法
User.objects.get_queryset().get() # 调用QuerySet的get方法
# 即:objects不是QuerySet对象,也没有继承QuerySet对象,但是有QuerySet对象的部分方法和属性,我们重写了get()方法,同时我们也可以objects.get_queryset()获取到QuerySet对象,然后再进行其他操作。
既然,objects有QuerySet对象的部分方法和属性,那么如果重写QuerySet对象,并添加或者重写get、filter等方法也可以:
from django.db import models
# 定义用户模型查询集合类,继承自django模型查询集合类:QuerySet
class UserQuerySet(models.QuerySet):
# 添加自定义方法
def find_self(self, **params)
pass
# 重写get方法
def get(self, **params)
pass
# 定义用户模型类
class User(models.Model):
# 指定用户模型管理器类
objects = UserQuerySet().as_manager()
# 使用
User.objects.find_self()
User.objects.get() # 重写后的get方法
User.objects.get_queryset().get() # 调用QuerySet的get方法,与User.objects.get()结果一样