Django …我们都知道这个Python框架在世界范围内的流行。这个框架使开发人员的生活更轻松。开发人员在 Django 中构建成熟的 Web 应用程序变得更加容易。如果您是一位经验丰富的 Django 开发人员,那么您肯定已经了解该项目的流程。 Django 样板文件中的运行方式以及数据如何呈现给用户。
Django 在 MVT 概念上工作,我们主要在其中处理两种类型的视图……基于类的视图和基于函数的视图。如果您是 Django 框架的新手,那么您肯定一直在使用 FBV(基于函数的视图)。
最初, Django以基于函数的视图开始,但后来 Django 添加了基于类的视图的概念,以避免样板中的代码冗余。开发人员之间争论不休,哪个更适合在 Django 中使用……基于类的视图还是基于函数的视图?今天在这篇博客中,我们将深入讨论这个话题,以了解两种观点的优缺点。
您可以使用它们来完成您的任务。有些任务可以使用 CBV 最好地实现,而其中一些任务可以在 FBV 中实现。 Django 视图主要有三个要求……
- 它们是可调用的。您可以使用基于函数或基于类的方式编写视图。使用 CBV 时,您会继承 as_view() 方法,该方法使用 dispatch() 方法调用适合的方法,具体取决于 HTTP 动词(get、post)等。
- 作为第一个位置参数,Django 视图应该接受 HttpRequest。
- 它应该返回 HttpResponse对象,或者应该引发异常。
现在让我们比较这两种观点,看看它们的优缺点。
1. 基于函数的视图
基于函数的视图非常适合初学者。与基于类的视图相比,它很容易理解。最初,当您想专注于核心基础知识时,使用基于函数的视图有利于理解它。让我们讨论一下它的一些优点和缺点。
优点:
- 易于阅读、理解和实施。
- 显式代码流
- 装饰器的直接使用。
- 适合专门的功能。
缺点:
- 代码冗余且难以扩展
- 条件分支将用于处理 HTTP 方法。
正如我们所讨论的,基于函数的视图很容易理解,但由于大型 Django 项目中的代码冗余,您会在视图中发现类似的函数。你会发现类似的代码被不必要地重复了。
这是基于函数的视图的示例……
Python3
def example_create_view(request, pk):
template_name = 'form.html'
form_class = FormExample
form = form_class
if request.method == 'POST':
form = form_class(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('list-view'))
return render(request, template_name, {'form': form})
Python3
class MyCreateView(View):
template_name = 'form.html'
form_class = MyForm
def get(self, request, *args, **kwargs):
form = self.form_class
return render(request, template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save()
return HttpResonseRedirect(reverse('list-view'))
else:
return render(request, self.template_name, {'form': form})
Python3
urlpatterns = [
url(r'^new/$', MyCreateView.as_view(), name='original-create-view')
url(r'^new_two/$', MyCreateView.as_view(template_name='other_form.html',
form_class='MyOtherForm'), name='modified-create-view')
]
Python3
from django.views.generic import CreateView
class MyCreateView(CreateView):
model = MyModel
form_class = MyForm
Python3
from django import forms
from . models import MyModel
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['name', 'description']
您在基于类的视图中找不到 FBV 的所有上述缺点。您不必在样板中一遍又一遍地编写相同的代码。
2. 基于类的视图
基于类的视图是基于函数的视图的替代品。它在项目中作为Python对象而不是函数实现。基于类的视图不会取代基于函数的视图,但与基于函数的视图相比,它们确实具有某些优势。基于类的视图负责基本功能,例如删除项目或添加项目。
如果您是初学者,使用基于类的视图并不容易。您必须仔细阅读文档,并且必须正确地研究它。一旦您了解了 Django 中的基于函数的视图并且您的概念清晰,您就可以转向基于类的视图。让我们详细讨论基于类的视图。
优点
- 基于类的视图最显着的优点是继承。在基于类的视图中,您可以继承另一个类,并且可以针对不同的用例对其进行修改。
- 它可以帮助您遵循 DRY 原则。您不必在样板中一遍又一遍地编写相同的代码。在基于类的视图中代码可重用性是可能的。
- 您可以扩展基于类的视图,并且可以使用 Mixin 添加更多功能。
- 使用基于类的视图的另一个优点是代码结构化。在基于类的视图中,您可以使用不同的类实例方法(而不是基于函数的视图中的条件分支语句)来生成不同的 HTTP 请求。
- 内置通用的基于类的视图。
缺点
- 实施复杂且难以阅读
- 隐式代码流。
- 视图装饰器中需要额外的导入或方法覆盖。
下面是一个基于类的视图的例子……
蟒蛇3
class MyCreateView(View):
template_name = 'form.html'
form_class = MyForm
def get(self, request, *args, **kwargs):
form = self.form_class
return render(request, template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
form.save()
return HttpResonseRedirect(reverse('list-view'))
else:
return render(request, self.template_name, {'form': form})
我们有一些抽象,方法 as_view() 正在调用 dispatch() 来确定需要执行哪个类方法,具体取决于 HTTP 请求。 as_view() 允许您覆盖 URL confs 中的类属性。您可以执行以下操作…
蟒蛇3
urlpatterns = [
url(r'^new/$', MyCreateView.as_view(), name='original-create-view')
url(r'^new_two/$', MyCreateView.as_view(template_name='other_form.html',
form_class='MyOtherForm'), name='modified-create-view')
]
一旦您开始使用 Django 通用的基于类的视图,您将能够覆盖像 get_form_class 和 get_template_names 这样的辅助方法。您可以在这些点插入附加逻辑,而不仅仅是覆盖类属性。
一个很好的例子是……ModelFormMixin。 form_valid 方法被覆盖。使用存储在 self.object() 中的更新值 form_valid 方法被覆盖。
3. Django 通用的基于类的视图
创建新对象、表单处理、列表视图、分页、存档视图所有这些都是 Web 应用程序中的常见用例。它来自 Django 核心,您可以从模块 django.views.generic 中实现它们。通用的基于类的视图是执行所有这些任务的绝佳选择。它加快了开发过程。
Django 提供了一组视图、mixin 和基于类的通用视图。利用它,您可以解决 Web 开发中最常见的任务。
主要目标不是减少样板。它使您免于一次又一次地编写相同的代码。修改 MyCreateView 继承自 django.views.generic.CreateView。
蟒蛇3
from django.views.generic import CreateView
class MyCreateView(CreateView):
model = MyModel
form_class = MyForm
您可能会认为所有代码都消失了。答案是这一切都在 django.views.generic.CreateView 中。当您从 CreateView 继承时,您将获得许多功能和快捷方式。您也认同某种“约定胜于配置”。风格安排。让我们再讨论一些细节……
默认情况下,模板应位于/
- 我们还需要声明 model 和 form_class 属性。从 CreateView 继承的方法依赖于它们。
- 您必须将 success_url 声明为视图上的类属性,或者必须在模型中指定get_absolute_url() 。这对于样板中的视图很重要,否则视图将不知道在成功提交表单后重定向到哪里。
- 在表单中定义字段或在视图上指定字段类属性。在此示例中,您可以选择执行后者。
查看下面给出的示例以检查它的外观。
蟒蛇3
from django import forms
from . models import MyModel
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['name', 'description']
结论
开发人员之间仍然争论哪种好用。基于类的视图还是基于函数的视图?我们已经讨论了它们的优缺点,但这完全取决于上下文和需求。我们已经提到基于类的视图不会取代基于函数的视图。在某些情况下,基于函数的视图更好,而在某些情况下,基于类的视图更好。
在列表视图的实现中,您可以通过继承 ListView 并覆盖属性来使其工作。在您需要执行更复杂的操作,同时处理多个表单的场景中,基于函数的视图将是您更好的选择。