def index3(request): # 查找文章题目中包含中国的文章分类 category = Category.objects.filter(article__title__contains='中国') print(type(Category.objects)) print(type(category)) # print(category.query) return HttpResponse("success!")
<class 'django.db.models.manager.Manager'>
<class 'django.db.models.query.QuerySet'>python
class Manager(BaseManager.from_queryset(QuerySet)): pass
# 在这里没有写明BaseManager是继承了哪一个类,默认状况下就是继承了objects。即为class BaseManager(objects): class BaseManager: @classmethod # 传进来的参数cls表明的是当前的类名BaseManager, # queryset_class:表明的是from_queryset()接收的值QuerySet,而class_name为默认值None def from_queryset(cls, queryset_class, class_name=None): # 由于咱们的from_queryset()方法只接受一个参数,因此class_name为None,知足if条件 if class_name is None: # class_name=BaseManagerFromQuerySet class_name = '%sFrom%s' % (cls.__name__, queryset_class.__name__) # type()函数能够用来动态建立类:返回type(建立的类名:BaseManagerFromQuerySet,继承的类:能够是单继承也能够是多继承,用元组表示:(cls,), class_dict) # class_dict:{ # '_queryset_class': QuerySet, # **cls._get_queryset_methods(QuerySet):表明的是调用当前类BaseManager的_get_queryset_methods()方法所获得的返回值。一样咱们能够将鼠标放在_get_queryset_methods()方法上,ctrl+b查看方法的返回值。 } return type(class_name, (cls,), { '_queryset_class': queryset_class, **cls._get_queryset_methods(queryset_class), })
class BaseManager: @classmethod def _get_queryset_methods(cls, queryset_class): # create_method()方法中传递两个参数name和method,返回的是manager_method, 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 = {} # 遍历QuerySet的函数,找到name和method for name, method in inspect.getmembers(queryset_class, predicate=inspect.isfunction): # Only copy missing methods. # hasattr(cls,name)返回的对象是否具备给定名称的属性,若是返回值为True就继续如下操做 if hasattr(cls, name): continue # 拷贝公共的方法或者是属性queryset_only=False的方法。 # 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. # 在这里咱们能够将鼠标放在create_method()方法上,ctrl+b,查看该方法执行的操做:返回了一个manager_method(manager方法名)被赋值给new_methods new_methods[name] = create_method(name, method) # 将拷贝的多个函数都返回给new_methods,而且返回new_methods. # 此时的_get_queryset_methods(QuerySet)的返回值就是拷贝的多个QuerySet的方法。 return new_methods
# class_dict:{ # '_queryset_class': QuerySet, # **cls._get_queryset_methods(QuerySet):获得拷贝的QuerySet的多个方法 # }
class Manager(BaseManager.from_queryset(QuerySet)): pass