(拜托 我这才是真的原理好么。。。网上看了一堆 都是使用方式?也可能我没找到真的原理。。。)
part1 加载过程
1、test/model.py
from django.db import models
class A(models.Model):
name = models.CharField()
class Meta:
db_table = "approve"
2、test/views.py
A.objects.filter(name='haha')
继承的models.Model
取的是
django/db/models/base.py
里class Model(six.with_metaclass(ModelBase)):
class Model
是元类ModelBase
的类对象,实现save() delete()
ModelBase
主要有三个方法,newclass时候调用add_to_class增加一堆_meta属性、_prepare方法绑定manager
,然后返回class
copy_managers(cls, base_managers)
:给cls添加base_managers里的manager属性add_to_class(cls, name, value)
:实现setattr(cls, name, value)
_prepare(cls)
:发信号、读取options.py的_prepare方法,基础上重写,然后再实现ensure_default_manager(cls)
ensure_default_manager
这个方法在manager.py中,主要目的实现下面两行。
# Ensures that a Model subclass contains a default manager and sets the
_default_manager attribute on the class. Also sets up the _base_manager
points to a plain Manager instance (which could be the same as
_default_manager if it's not a subclass of Manager).
cls.add_to_class('objects', Manager())
cls._base_manager = cls.objects
然后Manager()是啥呢?带有QuerySet信息的BaseManager对象
from django.db.models.query import QuerySet
class Manager(BaseManager.from_queryset(QuerySet)):
pass
# BaseManager.from_queryset,创建class,并把queryset_class方法列表加到类里面
@classmethod
def from_queryset(cls, queryset_class, class_name=None):
……
#BaseManager._get_queryset_methods,返回queryset_class方法列表
for循环:
class_dict.update(cls._get_queryset_methods(queryset_class))
return type(class_name, (cls,), class_dict)
————————————
所以,写了class A(models.Model)以后,orm会自动为类创建object方法,值为Manager()对象,然后Manager()对象返回的是一个类,这个类具有一堆queryset方法,并且orm为当前类初始化一些_meta信息
————————————
part2 queryset工作方式
django/db/models/query.py
,class QuerySet(object)
上面from_queryset
方法内用for循环了queryset_class
所以调用时候就会循环class QuerySet(object)
的def __iter__(self)
方法
顺序如下:
def __iter__(self)
——>def _fetch_all(self)
——>def iterator(self)
def iterator(self):
"""
An iterator over the results from applying this QuerySet to the
database.
"""
db = self.db
# 获取sql编译器,准备编译sql语句
compiler = self.query.get_compiler(using=db)
# 获取结果
results = compiler.execute_sql()
……
for row in compiler.results_iter(results):
obj = model_cls.from_db(db, init_list, row[model_fields_start:model_fields_end])
……
yield obj