django orm運行流程

(拜託 我這纔是真的原理好麼。。。網上看了一堆 都是使用方式?也可能我沒找到真的原理。。。)

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.pyclass 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.pyclass 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章