代码之家  ›  专栏  ›  技术社区  ›  Ben P

显示在Django模型中创建的项目总数

  •  3
  • Ben P  · 技术社区  · 6 年前

    我的Django项目包含一个包含项目和任务的任务管理器,我有一个通用列表页,显示所有项目的列表,其中包含有关其总任务的信息:

    class IndexView(generic.ListView):
        template_name = 'projects/index.html'
        context_object_name = 'project_list'
    
        def get_queryset(self):
            """Return 10 projects."""
            return Project.objects.order_by('is_complete')[:10]
    

    我想在我的列表页面上显示添加的项目和任务的总数,但我不确定该如何处理。我目前的所有工作都是列出每个项目中包含的任务数,但是现在我想要一个总数——我应该把这个作为一个新视图添加吗?例如,我尝试将此添加到上面的视图中:

    def total_projects(self):
        return Project.objects.count()
    

    然后打电话 {{ project_list.total_projects }} 在我的模板上,但它不返回任何内容。

    视图是否正确?

    2 回复  |  直到 6 年前
        1
  •  1
  •   17slim    6 年前

    我认为将函数定义放在模型类中更常见( Project 从外观上看),并添加 @property 标记在函数上方。

    class Project(models.Model):
        ''' definitions and stuff '''
    
        @property
        def total_projects(self): # etc...
    

    对于您的具体情况,您可以完全放弃该函数,只需使用 {{ project_list.count }} {{ project_list|length }} 在模板中。

    关于…的笔记 count VS length docs :

    count()调用在后台执行select count(*),因此 应始终使用count(),而不是将所有记录加载到 python对象并对结果调用len()(除非需要 无论如何,将对象加载到内存中,在这种情况下,len()将 更快)。

    请注意,如果要查询集中的项数,并且 从中检索模型实例(例如,通过迭代 它)使用len(queryset)的效率可能更高,它将 导致额外的数据库查询,如count()。

    所以使用正确的方法。

    另外,根据 this answer 以及来自@djangomachine的以下评论, 长度 可能不会总是返回与 计数 . 如果准确度很重要,最好使用 计数 不管上述情况如何。

        2
  •  2
  •   RompePC    6 年前

    所有按当前工作列出的任务数量都包括在每个项目中,但现在我想要一个总数-我应该把这个作为一个新视图添加吗?

    这要看情况而定。如果只想显示数据库中前10个已完成项目的项目和任务总数(这是 get_queryset 方法可以,小心点),我会在同一个视图中执行所有操作(创建一个新视图只显示一些数字是无用的,这不是 ListView 国际海事组织。

    另一方面,您正在调用类的实例方法( total_projects )从模型的实例。该方法在模型中不存在,并且当在模板中调用对象时,如果该对象中不存在属性/方法,则什么也得不到。基于上一段,我将在视图上下文中使用 get_context_data :

    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)
        data["total_projects"] = Projects.objects.count()
        # I'm assuming you only need the whole number of tasks with no separation
        data["total_tasks"] = Task.objects.count()
    
        return data
    

    最后,您可以编辑 GET-SqQueSeSET 方法并使其成为 instance attribute (如果您希望它更干净,并且可以在不使用附加代码的情况下处理筛选):

    class IndexView(generic.ListView):
        queryset = Project.objects.order_by('is_complete')[:10]