【问题标题】:Django sum of time differences from model fields模型字段的 Django 时间差总和
【发布时间】:2021-08-16 20:26:24
【问题描述】:

我正在尝试从 Django 中的模型字段中获取时间差的总和。我已经尝试过了,但我得到了一个没有错误的空结果:

model.py

class Project(models.Model):
    design_start = models.DateField(editable= True, default=datetime.today, blank=True)
    design_end = models.DateField(editable= True, default=datetime.today, blank=True)

class Portfolio(models.Model):
    projects = models.ManyToManyField(Project)

我试图通过从 design_end 中减去 design_start 得到所有项目的总设计时间,然后得到所有项目的总和

views.py

class DashView(generic.ListView):
    context_object_name = 'project_list'    
    template_name = 'index.html'
    queryset = Project.objects.all()
    def get_context_data(self, **kwargs):
        context = super(DashView, self).get_context_data(**kwargs)
        context['design_time'] = Portfolio.objects.all().annotate(
            design_time = ExpressionWrapper(Sum(F('projects__design_end') - F('projects__design_start')),
            output_field=DurationField()),
            )    
        return context

urls.py

urlpatterns = [
    path('', views.DashView.as_view(), name='home'),
    ]

index.html

<h4>{{ design_time.design_time }}</h4>

【问题讨论】:

  • design_time 是一个QuerySet,因此没有design_time.design_time,你需要在它上面循环...
  • @AbdulAzizBarkat 感谢您的回复。我试过这个:{% for time in design_time %}{{ time }} {% endfor %},我得到了这个错误:'You cannot use Sum, Avg, StdDev, and Variance' django.db.utils.NotSupportedError: You cannot use Sum, Avg, StdDev, and Variance 聚合sqlite3 中的日期/时间字段,因为日期/时间保存为文本。
  • 我已针对该错误编辑了答案,请检查。

标签: python django view model


【解决方案1】:

在你看来,你写道:

context['design_time'] = Portfolio.objects.all().annotate(design_time=...)

这里您选择的密钥不是很具有描述性(即使您似乎被您的这个名字所欺骗)。这里design_timePortfolio 对象的QuerySet,因此没有design_time.design_time 这样的东西。相反,如果您遍历design_time,您将获得Portfolio 实例,这些实例将在它们上注释design_time。为了更具描述性,首先在上下文中将此键重命名为:

context['portfolios'] = Portfolio.objects.all().annotate(design_time=...)

模板循环中的下一步:

{% for portfolio in portfolios %}
    {{ portfolio.design_time }}
{% endfor %}

在您的查询中,您在Sum 上使用ExpressionWrapper,而不是在ExpressionWrapper 上使用Sum

Portfolio.objects.all().annotate(
    design_time = Sum(
        ExpressionWrapper(
            F('projects__design_end') - F('projects__design_start'),
            output_field=DurationField()
        )
    )
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 2011-11-19
    • 2011-10-27
    • 2013-08-17
    • 1970-01-01
    相关资源
    最近更新 更多