gpt4 book ai didi

python - 在django.shortcuts.render和django.views.generic.TemplateView之间选择

转载 作者:行者123 更新时间:2023-12-01 01:39:39 25 4
gpt4 key购买 nike

我已经看过几个Django教程。

我注意到基于静态HTML模板文件生成动态Web内容,有2种方法


django.conf.urls.url中使用url.py。指向将调用django.shortcuts.render的命名函数。
django.urls.path中使用url.py。指向一个从django.views.generic.TemplateView继承的命名类。


两种方式产生相同的结果。

我想知道,如何确定给定情况下使用哪种方式?

最佳答案

基于类的视图(CBV)和基于函数的视图(FBV)可以做相同的事情:在特定视图在功能上等效的意义上,始终可以将CBV“转换”为FBV,反之亦然。

支持基于类的视图(CBV)

CBV通常用于抽象出通用逻辑。例如,在模板视图中,您无需调用render(..),这对我们来说是隐式完成的:我们只需要提供模板的名称即可。此外,如果稍后发现某个“代码流”存在问题,可以很容易地在特定视图中对此进行修补,因此所有视图都可以立即修复,而如果错误位于FBV中,则我们需要修补所有这些FBV。

它还将视图拆分为一组可重用的组件:例如,一个DetailView具有一个用于计算要渲染的对象的组件,一个可以向上下文中添加额外数据的组件以及执行实际渲染的方法。 。如果以后要允许在该视图上发出POST请求,则已经有那些组件可用。

CBV还可以通过使用面向对象的技术(如(多个)继承和混合)轻松地创建临时控制流:无需实现特定的控制流,可以定义一个混合,然后将其混合到应具有的视图中控制流发生了变化。

这也使子视图的子类化变得很容易:如果您有一个显示所有记录的视图,则需要两层衬里,才能对该视图进行子类化以在新视图中对记录进行分页。如果以后再更改旧的记录视图,则此更改也会立即对所有子类产生影响(但是,有时可能会产生不利的副作用)。

从某种意义上来说,不同的HTTP请求的处理也更简洁,因为它们是单独的方法(视图可以具有get(..)post(..)patch(..)等方法),而在基于函数的视图中,通常用if request.method == 'POST'处理。通常,这会导致以下事实:处理非POST请求(例如PATCH)就像是GET一样,而建议您返回“ 405 Method Not Allowed”错误。可以通过基于函数的视图来完美地解决此问题,但是这需要一些额外的工作,因此经常被忽略。

最终,Django有许多通用的View子类来处理常见情况,例如呈现对象列表,创建或更新模型对象的新实例等。许多用例(几乎)完全被CBV覆盖,因此只需要子类化该特定视图,然后填写详细信息(模板名称,对模型的引用等)。这也导致了更具声明性的编程:说出您想要的内容,而不是您想要的内容。例如,Django的ListView支持分页。

支持基于功能的视图(FBV)

但是,基于函数的视图显示了控制流,而在基于类的视图中,这是隐藏的,因此更像是Django魔术。由于所有操作都是在“幕后”进行的,因此无法看到控制流会使调试视图变得更加困难,并且由于某些视图的某些特殊性,可能会发生错误。

基于函数的视图也往往更易于实现:您获得一个request对象以及可选的一些(URL)参数,并且需要将其转换为HTTP响应。您不必为我需要获取哪个对象而推理:您可以简单地在函数中以即席样式获取对象(当然,您也可以在CBV中执行此操作,但这并不是a背后的想法。 CBV)。

最终,Django还提供了大量功能装饰器,例如@login_required(CBV有相应的部分)。通常,对函数装饰器的含义进行推理要比对视图子类化的含义进行推理更容易:子类化可以对视图的所有方法产生影响。此外,具有多重继承的子类化并不总是那么简单:Python使用方法解析顺序(MRO)来确定super().some_method()是什么,但这可能会导致一些棘手的副作用,而<<的实现者可能没有预见到这些副作用。 cc> s或查看mixins。

Django转向基于类的视图

但是,当您查看Django的开发时,您会看到从基于函数的视图向基于类的视图的转变:例如,在中,已删除了基于View基于函数的视图。在中引入了CBV对应项(login)。但是,这并不意味着Django开发人员必须将所有内容都编写为CBV:Django通常涵盖相当通用的视图,因此在这种情况下使用CBV更有意义。

关于python - 在django.shortcuts.render和django.views.generic.TemplateView之间选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52024378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com