何时覆盖 Django CBV 中的 get 方法?

When to override get method in Django CBV?

我一直在学习 Django,我感到困惑的原因之一是基于 class 的视图以及何时重写 get 方法。我查看了文档,它解释了 get 的作用,但没有解释我何时应该覆盖 get。

我最初是这样创建视图的:

class ExampleView(generic.ListView):
    template_name = 'ppm/ppm.html'
    paginate_by = 5

    def get(self, request):
        profiles_set = EmployeeProfile.objects.all()
        context = {
            'profiles_set': profiles_set,
            'title': 'Employee Profiles'
        }
        return render(request, self.template_name, context)

但最近有人告诉我,我的代码对于默认实现来说已经足够简单了,我需要的只是这个:

class ExampleView(generic.ListView):
    model = EmployeeProfile
    template_name = 'ppm/ppm.html'

所以我的问题是:我应该在什么地方 scenario/circumstance 覆盖 get 方法?

当您特别想做默认视图以外的事情时,您应该覆盖 get 方法。在这种情况下,除了使用所有 EmployeeProfile 对象的列表呈现模板之外,您的代码没有做任何事情,这正是通用 ListView 会做的。

如果你想做一些更复杂的事情,你可以覆盖它。例如,也许您想根据 URL 参数进行过滤:

class ExampleView(generic.ListView):
    template_name = 'ppm/ppm.html'

    def get(self, request):
        manager = request.GET.get('manager', None)
        if manager:
            profiles_set = EmployeeProfile.objects.filter(manager=manager)
        else:
            profiles_set = EmployeeProfile.objects.all()
        context = {
            'profiles_set': profiles_set,
            'title': 'Employee Profiles'
        }
        return render(request, self.template_name, context)

如果您使用的是内置通用视图,那么您应该很少需要重写 get()。您最终要么复制大量功能,要么破坏视图的功能。

例如,paginate_by 选项在您的视图中将不再有效,因为您没有在 get() 方法中对查询集进行切片。

如果您使用的是通用的基于 class 的视图,例如 ListView,您应该尽可能尝试覆盖特定的属性或方法,而不是覆盖 get().

您的视图覆盖 get() 的优点是它的作用非常清楚。您可以看到视图获取一个查询集,将其包含在上下文中,然后呈现模板。您无需了解 ListView 即可理解该视图。

如果您喜欢直接覆盖 get() subclass View。您没有使用 ListView 的任何功能,因此子 class 它没有意义。

from django.views.generic import View

class ExampleView(View):
    template_name = 'ppm/ppm.html'

    def get(self, request):
        ...