数据库表如下
#models.py
class Author(models.Model):
"""作者模型"""
name = models.CharField(max_length=100)
age = models.IntegerField()
email = models.EmailField()
class Meta:
db_table = "author"
#views.py
from .models import Author
def queryset(request):
authors = Author.objects.all()
print(authors)
return HttpResponse("success")
Author类的objects属性
def queryset(request):
# authors = Author.objects.all()
# print(authors)
print(type(Author.objects))
return HttpResponse("success")
>>><class 'django.db.models.manager.Manager'>
Author.objects是django.db.models.manager.Manager
类的实例,导入Manager
类查看源码:
django.db.models.manager.Manager
class Manager(BaseManager.from_queryset(QuerySet)):
pass
Manager
类继承自BaseManager.from_queryset(QuerySet)
,调用BaseManger
的类方法from_queryset
,参数是QuerySet
类
QuerySet类里有什么
可以查看类结构,有all方法,filter方法,order_by方法,aggregate方法,annotate方法等...,发现都是操作ORM时用到的方法
BaseManager.from_queryset(QuerySet)源码查看
@classmethod
def from_queryset(cls, queryset_class, class_name=None):
if class_name is None:
class_name = '%sFrom%s' % (cls.__name__, queryset_class.__name__)
class_dict = {'_queryset_class': queryset_class,} # class_dict = {'_queryset_class': QuerySet,}
class_dict.update(cls._get_queryset_methods(queryset_class))
return type(class_name, (cls,), class_dict)
前两句代码翻译如下:
class_name = '%sFrom%s' % (cls.__name__, queryset_class.__name__) # class_name = "BaseManagerFromQuerySet"
class_dict = {'_queryset_class': queryset_class,} # class_dict = {'_queryset_class': QuerySet,}
class_dict.update(cls._get_queryset_methods(queryset_class))
查看BaseManger._get_queryset_methods(QuerySet)
类方法源码:
@classmethod
def _get_queryset_methods(cls, queryset_class):
def create_method(name, method):
def manager_method(self, *args, **kwargs):
return getattr(self.get_queryset(), name)(*args, **kwargs)
manager_method.__name__ = method.__name__
manager_method.__doc__ = method.__doc__
return manager_method
new_methods = {}
# Refs http://bugs.python.org/issue1785.
predicate = inspect.isfunction if six.PY3 else inspect.ismethod
for name, method in inspect.getmembers(queryset_class, predicate=predicate):
# Only copy missing methods.
if hasattr(cls, name):
continue
# Only copy public methods or methods with the attribute `queryset_only=False`.
queryset_only = getattr(method, 'queryset_only', None)
if queryset_only or (queryset_only is None and name.startswith('_')):
continue
# Copy the method onto the manager.
new_methods[name] = create_method(name, method)
return new_methods
将QuerySet类中的指定方法拷贝到new_methods字典,返回new_methods。
更新class_dict
,参数是new_methods这个字典,class_dict中没有的键会新增,如果键存在,覆盖键对应的值。
type(class_name, (cls,), class_dict)作用是动态创建类
即type(BaseManagerFromQuerySet, (BaseManager,), class_dict)
第一个参数:指定创建的类的名字,创建的类名是BaseManagerFromQuerySet
第二个参数:指定创建类的父类,使用元祖是因为支持多继承
第三个参数:指定创建类拥有的属性和方法,即class_dict
最终返回新创建的类作为Manager的父类
因为拷贝了QuerySet类的部分方法,所以可以调用Author.objects.all()等方法
网友评论