Django 类视图和函数视图之间的区别
Django是最受欢迎的Web开发框架之一。它之所以受欢迎,是因为提供了许多内置功能,可以节省开发人员的大量时间。如果你是初学者,理解项目流程可能需要一些时间。但是一旦你有了一些经验,你就可以轻松理解功能的执行过程。
Django基于MVT(模型视图模板)模式。我们主要使用两种类型的视图:函数视图和类视图。如果你是初学者,你必须熟悉函数视图(FBV)。
当Django刚推出时,它只支持函数视图,但后来Django添加了类视图的概念。类视图减少了代码的冗余。它还支持Django的DRY(不重复自己)原则。
在本教程中,我们将深入学习FBV和CBV之间的区别。我们可以使用函数视图和类视图执行相同的任务,但两种方式不同。
Django视图的要求
以下是我们应该记住的关于Django视图的要点。
- 视图的第一个位置参数应为
- 应该返回 HttpResponse 对象,或抛出异常。
- Django视图是可调用的。我们可以使用函数式视图或类视图的方法。当使用CBV时,我们继承方法 as_view() ,该方法使用 dispatch() 方法根据HTTP请求调用适当的方法。
让我们详细解释一下创建视图的方式。
函数视图
函数视图使用简单,初学者可以轻松理解。它有助于理解Django基础概念的核心。FBV从头开始提供了理解Django概念的优势。
Django项目通常包含CRUD操作,因此我们需要多次实现相同的代码,这是不必要的,这就是Django类视图出现的场景。类视图解决了代码冗余问题。让我们了解以下FBV的优点和缺点。
函数视图的优点
FBV的优点如下。
- 易于实现,阅读和理解
- 代码流程清晰
- 易于实现装饰器
- 适用于一次性或特定功能
- 有助于理解Django的核心概念。
函数视图的缺点
FBV的缺点如下。
- 代码冗余是FBV最大的问题。
- 需要使用条件分支处理HTTP请求。
- 代码难以扩展。
让我们了解以下FBV的实现。
代码
def create_view(request, pk):
template_name = 'form.html'
form_class = MyForm
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})
类视图
类视图是在Python中创建视图的一种高级方式。它在项目中以Python对象的形式实现,而不是函数。它并不取代FBV,但它比函数视图提供了一些优势。它减少了代码重复,并处理了基本操作,如删除和添加项目。
对于初学者来说,理解类视图的概念有一点难度。您应该阅读文档并进行适当的学习。如果您对函数视图有清楚的了解,那么可以尝试类视图。
让我们了解一下Python视图的以下优缺点。
类视图的优点
以下是类视图的优点:
- CBV最大的优势之一是继承。CBV允许我们继承另一个类并对其进行修改以适应不同的用例。
- 它支持DRY原则。它防止代码重复。类视图中可以重用代码。
- 它带有内置的通用类视图。
- 类视图提供了适当的代码结构。我们可以使用不同的类实例方法(而不是在函数视图中使用条件分支语句)来生成HTTP请求。
类视图的缺点
以下是类视图的缺点:
- 难以理解和实现复杂的功能。
- 隐式的代码流。
- 在视图装饰器中需要额外的导入或方法覆盖。
让我们看一下类视图的实现。
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()方法来对用户的请求进行处理。as_view()方法调用dispatch()方法来确定根据HTTP请求需要执行哪个类方法。我们可以按照以下方式实现它。
urlpatterns = [
url(new/', MyCreateView.as_view(), name='original-create-view'),
url(new_two/', MyCreateView.as_view(), name='modified-create-view')
]
当我们使用Django的泛型基于类的视图时,我们可以重写帮助方法,例如get_form_class和get_template_names。我们还可以在这些点添加一些自定义逻辑,而不仅仅是覆盖类属性。
ModelFormMixin是最好的示例之一。form_valid方法被覆盖,并通过self.object存储的更新值进行了重写。
Django泛型基于类的视图
借助泛型基于类的视图,我们可以执行一些重要的任务,如创建新对象、列表视图、分页、表单处理、存档视图、删除视图等。
我们可以通过导入django.views.generic来实现这一点。泛型基于类的视图是执行一些重要任务的绝佳方式,它加快了开发过程。
Django提供了一组mixins和泛型基于类的视图。借助这些工具,我们可以解决Web开发中最常见的任务。
它避免了我们重复编写相同的代码。在下面的示例中,我们可以修改MyCreateView以继承自django.views.generic.CreateView。
from django.views.generic import CreateView
class FirstCreateView(CreateView):
model = MyModel
form_class = MyForm
正如我们所观察到的,与之前的视图相比,代码量要少得多。django.views.generic.CreateView提供了许多内置功能和快捷方式。让我们再讨论一些细节。
默认情况下,模板应该位于//_form.html。我们可以通过设置类属性 template_name 和 template_name_sufix 来进行修改。
- 在CreateView类中,我们需要指定模型名称和form_class_attributes。
- 我们还需要指定success_url,成功提交表单后将重定向到指定的页面。可以使用 get_absoute_url() 来实现。
- 我们可以在视图上指定字段的类属性。以下是表单字段的示例。
from django import forms
from . models import MyModel
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['name', 'description']
结论
这是开发人员之间的一个热门辩论,究竟使用基于类的视图还是基于函数的视图更好?我们已经讨论了两种类型视图的使用、优点和缺点。这完全取决于项目的需求和您个人的偏好。在某些情况下,基于类的视图表现良好,而在其他情况下,基于函数的视图更好。