何时在 Django 中使用 get、get_queryset、get_context_data?

2025-04-16 08:57:00
admin
原创
12
摘要:问题描述:我最近了解到,当您特别想执行默认视图以外的其他操作时,您应该重写 get 方法:class ExampleView(generic.ListView): template_name = 'ppm/ppm.html' def get(self, request): m...

问题描述:

我最近了解到,当您特别想执行默认视图以外的其他操作时,您应该重写 get 方法:

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'
            }

这很简单,但是什么时候应该使用get_querysetorget_context_data而不是get?在我看来,它们基本上做同样的事情,还是我忽略了什么?我可以一起使用它们吗?这对我来说是一个很大的困惑。

因此重申一下:在什么情况下我会使用 get overget_querysetget_context_data反之亦然?


解决方案 1:

他们确实做不同的事情。

get()

这是一个顶级方法,每个 HTTP 动词(例如 、 、 等)都有一个对应的方法。get()如果post()patch()想在视图处理请求之前或之后执行某些操作,可以重写该方法。但这仅在表单视图首次加载时调用,而不是在表单提交时调用。文档中提供了基本示例。默认情况下,它只会渲染配置的模板并返回 HTML。

class MyView(TemplateView):
    # ... other methods

    def get(self, *args, **kwargs):
        print('Processing GET request')
        resp = super().get(*args, **kwargs)
        print('Finished processing GET request')
        return resp

get_queryset()

由 s 使用ListView- 它决定了您想要显示的对象列表。默认情况下,它只会显示您指定模型的所有内容。通过重写此方法,您可以扩展或完全替换此逻辑。Django文档对此主题进行了介绍。

class FilteredAuthorView(ListView):
    template_name = 'authors.html'
    model = Author

    def get_queryset(self):
        # original qs
        qs = super().get_queryset() 
        # filter by a variable captured from url, for example
        return qs.filter(name__startswith=self.kwargs['name'])

get_context_data()

此方法用于填充字典,以用作模板上下文。例如, s 将填充上例中的ListView结果。您可能最常重写此方法,以添加要在模板中显示的内容。get_queryset()`author_list`

def get_context_data(self, **kwargs):
    data = super().get_context_data(**kwargs)
    data['page_title'] = 'Authors'
    return data

然后在您的模板中,您可以引用这些变量。

<h1>{{ page_title }}</h1>

<ul>
{% for author in author_list %}
    <li>{{ author.name }}</li>
{% endfor %}
</ul>

现在回答你的主要问题,你之所以有这么多方法,是为了让你能够轻松地精准地实现自定义逻辑。这不仅能让你的代码更具可读性和模块化,而且也更易于测试。

文档应该能解释一切。如果还不够,你可能会发现这些资源也很有帮助。你会看到所有东西是如何通过 mixin 实现的,而这只有在所有东西都被划分开来的情况下才有可能实现。

解决方案 2:

我们来看一下ListView的默认get方法实现:

https://github.com/django/django/blob/92053acbb9160862c3e743a99ed8ccff8d4f8fd6/django/views/generic/list.py#L158

class BaseListView(MultipleObjectMixin, View):
    """
    A base view for displaying a list of objects.
    """
    def get(self, request, *args, **kwargs):
        self.object_list = self.get_queryset()
        allow_empty = self.get_allow_empty()

        if not allow_empty:
            # When pagination is enabled and object_list is a queryset,
            # it's better to do a cheap query than to load the unpaginated
            # queryset in memory.
            if (self.get_paginate_by(self.object_list) is not None
                    and hasattr(self.object_list, 'exists')):
                is_empty = not self.object_list.exists()
            else:
                is_empty = len(self.object_list) == 0
            if is_empty:
                raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.")
                        % {'class_name': self.__class__.__name__})
        context = self.get_context_data()
        return self.render_to_response(context)

你会注意到它get_queryset在第一行就被调用了。如果你只想在应用一些过滤/排序等操作后返回模型的查询集,你可以简单地覆盖它。

您不需要get为此覆盖整个方法,因为您将错过所有提供的功能,即分页、404 检查等。

get_context_data将结果查询集与上下文数据(如分页的查询字符串参数等)合并在一起。

我的建议是时不时地检查一下 django 的源代码,并尝试稍微理解一下,这样你就可以识别出可以覆盖/替换的最合适的方法。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2482  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1533  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   0  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   0  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   0  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用