在views.py中,我们编写大约any_model_name.objects.all()个这样的代码,这个代码会给我们带来从any_model_name类模型开始的所有对象.我刚刚阅读了models.Model类中的所有代码(任何模型都应该继承的类),我只是找不到.objects属性出现的位置,也找不到.all()方法属性.我的pycharm也有同样的看法,它用红色下划线.objects,并写着"类‘any_Model_name’的未解析属性引用‘对象’".是什么魔法让我在Django代码中找不到第一次出现.objects东西的地方?

推荐答案

它是由metaclass添加的,但以一种有点加密的方式.事实上,在ModelBase_preprare级中,它不是Model的超级级,而是typeclass,contributes this to the class [src]:

    def _prepare(cls):
        # …
        if not opts.managers:
            # …
            cls.add_to_class("objects", manager)
        # …

.add_to_class方法将调用管理器上的.add_to_class,然后将其自身设置为类对象上的属性.

然而,每款车型都有.objects分的说法是不正确的.只有在您没有自己指定经理的情况下才会出现这种情况.事实上,如果你定义一个模型:

class MyModel(models.Model):
    mymanager = models.Manager()

MyManagernot包含.objects.

至于.all()方法本身,它与_get_queryset_methods一起工作.它们返回一个字典,其中包含方法及其方法的名称.因此,这将返回一个将'all'映射到返回self.get_queryset().all()的方法的字典,因为get_queryset将返回QuerySet,it will thus call .all() on that queryset [src]:

@classmethod
def _get_queryset_methods(cls, queryset_class):
    def create_method(name, method):
        @wraps(method)
        def manager_method(self, *args, **kwargs):
            return getattr(self.get_queryset(), name)(*args, **kwargs)

        return manager_method

    new_methods = {}
    for name, method in inspect.getmembers(
        queryset_class, predicate=inspect.isfunction
    ):
        # 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

大多数IDE、代码分析工具等确实无法推导出模型具有.objects属性,因为它源自类型类中的一些复杂代码.

然而,PyCharm专业版有一个Django插件,可以更好地"理解"Django,因为开发人员已经硬编码了这样的逻辑.因此,它包含了一些不分析类型类代码的逻辑,而只是知道,因为模块的开发人员说了这一点,经理补充道.

Python是一种非常灵活的、动态类型的语言,这通常是一个好主意.但代码分析有时不能遵循元类等的复杂性,因此最终无法看到如何将项添加到类中,这是一个缺点,例如,与静态类型语言相比.

Django相关问答推荐

未强制执行枚举值

带有变量键的 Django 模板括号表示法不起作用

try 获取静态文件路径时 Django 给出错误

在Django测试get方法中获取HttpResponseNotFound

在 Django 中处理信用卡付款的最佳 Select 是什么?

Playframework 和 Django

什么时候在 django rest 框架序列化程序中调用创建和更新?

可插拔应用程序的Django默认设置约定?

在 Django 中,您可以向查询集添加方法吗?

模型中的外键

在 virtualenv Ubuntu 12.10 中使用 pip 安装 lxml 错误:command 'gcc' failed with exit status 4

Django-获取外键模型

django-object-permissions Vs django-guardian Vs django-authority

在 Django Admin 中过滤多对多框

升级到 Django 1.8 后提供的固定默认值

Django 发送邮箱

Django:在还原(迁移)后try 访问数据库时权限被拒绝

如何在 Django 中更改上传文件的文件名?

Jinja2中的多级模板继承?

Django:根据自定义函数过滤查询