django orm运行流程

本文深入探讨Django ORM的工作原理,包括模型加载过程、元类ModelBase的作用、Manager的实现机制,以及QuerySet的工作方式。解析了ORM如何自动为模型类创建object方法,以及Manager()对象如何提供一系列queryset方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(拜托 我这才是真的原理好么。。。网上看了一堆 都是使用方式?也可能我没找到真的原理。。。)

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
<think>我们正在处理用户关于Django ORM模板使用教程的请求。根据用户需求,我们需要提供关于如何在Django模板中使用ORM查询结果的教程。注意,用户要求的是“模板中使用”,因此重点应放在如何在模板中展示ORM查询的数据,而不是ORM查询本身(虽然会涉及)。 根据系统指令,我们需要: 1. 使用$...$格式的行内数学表达式(但本问题可能不涉及数学表达式,所以可以忽略) 2. 独立公式使用$$...$$格式(同样,本问题可能不涉及) 3. 使用中文回答 4. 生成相关问题 5. 在引用的段落末尾添加引用标识(注意:我们有一些参考引用,但需要判断是否与回答内容相关) 另外,用户提供的引用内容是关于Django ORM的模型关系、分页、非空判断、添加用户和多表操作等,这些可以作为补充知识,但用户当前的问题是“模板使用”。 因此,我们将重点放在: 1. 如何在视图中使用ORM获取数据 2. 如何将数据传递给模板 3. 在模板中如何展示这些数据(包括循环、条件判断、显示字段等) 步骤: 1. 创建视图函数,在视图函数中执行ORM查询,并将查询结果传递给模板。 2. 配置URL,将请求映射到该视图。 3. 编写模板文件,使用Django模板语言(DTL)展示数据。 注意:用户可能对Django模板语言不熟悉,所以需要简单介绍。 我们参考的引用内容中,引用[1]提到了分页,引用[2]介绍了ORM的基本概念,引用[3]是关于非空判断,引用[4]和[5]是关于添加用户和多表操作。我们可以适当引用其中与模板展示相关的部分,比如分页(因为分页结果需要在模板中展示)和多表操作(因为多表查询的数据在模板中展示很常见)。 计划回答结构: 一、Django模板与ORM结合的基本流程 二、示例:在模板中展示单表数据 三、示例:在模板中展示多表关联数据(使用引用[5]中的多表操作示例) 四、分页数据的展示(使用引用[1]中的分页技术) 五、模板中的条件判断(如非空判断,可参考引用[3]) 然后生成相关问题。 注意:在回答中,如果引用了参考内容,需要在末尾添加引用标识。 开始编写回答:</think>### Django ORM模板使用教程 在Django中,ORM(对象关系映射)与模板系统的结合是开发动态网页的核心。以下是详细使用教程: #### 一、基础流程 1. **定义模型**(models.py) ```python from django.db import models class Book(models.Model): title = models.CharField(max_length=200) author = models.ForeignKey('Author', on_delete=models.CASCADE) publish_date = models.DateField() class Author(models.Model): name = models.CharField(max_length=100) email = models.EmailField() ``` 2. **视图处理数据**(views.py) ```python from django.shortcuts import render from .models import Book def book_list(request): # ORM查询:获取所有书籍及关联作者 books = Book.objects.select_related('author').all() return render(request, 'books/list.html', {'books': books}) ``` 3. **模板展示数据**(templates/books/list.html) ```django {% for book in books %} <div class="book"> <h2>{{ book.title }}</h2> <p>作者: {{ book.author.name }} ({{ book.author.email }})</p> <p>出版日期: {{ book.publish_date|date:"Y-m-d" }}</p> </div> {% endfor %} ``` #### 二、关键模板技术 1. **关联数据访问** - 直接通过点语法访问外键字段:`{{ book.author.name }}` - 多对多关系遍历: ```django {% for tag in book.tags.all %} <span>{{ tag.name }}</span> {% endfor %} ``` 2. **条件判断** ```django {% if book.publish_date.year > 2020 %} <span class="new">新书!</span> {% endif %} ``` 3. **空值处理**(参考引用[3]) ```django {% if book.description|default:""|length > 0 %} {{ book.description }} {% else %} <p>暂无简介</p> {% endif %} ``` #### 三、分页实现(参考引用[1]) 1. **视图添加分页** ```python from django.core.paginator import Paginator def book_list(request): books = Book.objects.all() paginator = Paginator(books, 10) # 每页10条 page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) return render(request, 'books/list.html', {'page_obj': page_obj}) ``` 2. **模板分页控件** ```django <div class="pagination"> {% if page_obj.has_previous %} <a href="?page=1">首页</a> <a href="?page={{ page_obj.previous_page_number }}">上一页</a> {% endif %} <span>页码 {{ page_obj.number }} / {{ page_obj.paginator.num_pages }}</span> {% if page_obj.has_next %} <a href="?page={{ page_obj.next_page_number }}">下一页</a> <a href="?page={{ page_obj.paginator.num_pages }}">末页</a> {% endif %} </div> ``` #### 四、表单处理(参考引用[4]) 1. **模板表单** ```django <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">添加书籍</button> </form> ``` 2. **表单视图** ```python def add_book(request): if request.method == 'POST': form = BookForm(request.POST) if form.is_valid(): form.save() # ORM直接保存 return redirect('book_list') else: form = BookForm() return render(request, 'books/add.html', {'form': form}) ``` #### 五、性能优化 1. **减少查询次数** - 使用`select_related()`处理一对一/多对一关系 - 使用`prefetch_related()`处理多对多关系 ```python # 视图优化查询 Book.objects.prefetch_related('tags').select_related('author') ``` 2. **模板缓存** ```django {% load cache %} {% cache 600 book_list %} <!-- 缓存10分钟 --> {% for book in books %}...{% endfor %} {% endcache %} ``` 通过掌握Django的模型关系和模板技术,开发者可以高效管理数据库和优化用户界面[^1]。Django ORM的灵活性和模板系统的强大功能值得每一位Web开发者深入学习和应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值