【问题标题】:Can Django template variables be model instances?Django 模板变量可以是模型实例吗?
【发布时间】:2015-09-10 17:22:48
【问题描述】:

我在一次采访中被问到这个问题大概是想看看我是否理解模板层和模型层之间的分离。

我的理解是,模板变量本质上是:

  1. 实例的静态副本(以便可以访问所有属性)
  2. 具有“隐藏”参数的所有方法的实例(这样它们不能被调用,但可以调用不带参数的方法)

因此,如果您有一个只有方法没有参数的模型并将一个实例传递给模板,您能说它是该实例的静态副本吗?这甚至是思考模板变量的正确方法吗?

更新:

模板(视图)层是否能够更新模型(例如,来自自定义上下文处理器)?如果不是,那么如果 Django 框架没有复制模型实例,它如何防止这种情况发生?如果是,那么这不是与典型的 Web 框架 MVC 设计的重大偏差,即数据仅沿一个方向从模型流向视图吗?

【问题讨论】:

  • 问“Django 变量”是否是“模型实例”是没有意义的。如果您将模型实例传递给 Django 模板,那么是的,该变量是模型实例;但你也可以传递一个字符串、int、其他类实例或任何你喜欢的东西,模板变量就是那种类型。
  • 不,将这些视为静态无方法副本是绝对错误的。

标签: python django django-templates


【解决方案1】:

问题不在于变量是静态副本。只是模板语言本身不允许你调用带参数的方法。它仍然是您正在访问的同一对象,您只是无法用语言表达某些编程概念(赋值、传递参数等)。

回答您的更新: 是的,如果模型具有修改对象的方法并且该方法不带任何参数,则模板层可以更新模型。但仅仅因为你可以做一件事并不意味着你应该做一件事。不要以为 Django 的开发人员没有绝对阻止某事就意味着它是完全可以接受的,但如果那是你真正想做的,没有什么可以阻止你。

【讨论】:

    【解决方案2】:

    Django 中的template 实际上是python 代码,它将html 文件中的已解析行转换为python 代码,并将其结果直接注入到生成的html 文件中。因此,传递给模板的所有对象和变量都被传递给完成所有工作的这个 python 代码(或函数/模块)。

    当你打电话时:

    render(request, 'template.html', {'data': [1,2,3...],})
    

    您实际上是在调用python 函数,该函数将文件template.html 作为参数,解析它,计算{{ }} 和{% %} 块中的任何行,并用结果替换它们。可以评估的操作数量是有限的,因为 Python 代码(或 模板引擎)不会评估这些函数。

    所以,为了回答您的疑问,传递给模板的实例变量实际上是传递给处理所有工作的 python 模板引擎,并调用要调用的方法。在支持哪些操作以及可以调用哪些方法方面,它就像 python 的一个子集。

    请记住,模板过滤器允许您通过传递给模板的实例变量调用带有参数的方法,模板过滤器被显式加载到模板引擎中。这就像 import 一样,模板引擎知道方法、参数和结果。

    【讨论】:

    • 所以你对这个问题的回答是肯定的?您还同意它们是静态副本还是未强制执行?如果模板引擎可能无意中更改模型数据并且实际上不再是 MVC,这似乎是一个糟糕的设计。
    • 您如何可能从这个答案中得到“是”?没有进行复制。
    • 正如@DanielRoseman 所说,您认为该对象是static,或者该对象的不可变副本是不正确的。对象引用像 python 中的任何其他对象引用一样传递。 Django 并不是传统意义上的“MVC”。如果你想从这个意义上考虑它,
    【解决方案3】:

    对于未来的读者,我的问题的核心与通过引用混淆有关。我忘记了 Python 如何处理传递给函数的对象。基本上,它不允许您从外部范围修改引用对象,请参阅here 和here。因此,数据很难意外流回模型(在桌面 MVC 实现中很容易发生)。

    我很惊讶没有人指出这一点,因为这是对 Python 的常见误解,所以我想在这里记录一下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-31
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多