简体   繁体   中英

Django sum of time differences from model fields

I'm trying to get the sum of time differences from model fields in Django. I've tried this but I get an empty result with no error:

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)

I'm trying to get the total design time of all the projects by subtracting design_start from design_end and then getting the sum of everything

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>

In your view you write:

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

Here your choice of the key is not very descriptive (even you were tricked by this name of yours it seems). Here design_time is a QuerySet of Portfolio objects, hence there is no such thing as design_time.design_time . Instead if you loop over design_time you will get Portfolio instances which will have design_time annotated onto them. To be more descriptive first rename this key in the context to something like:

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

Next in your template loop over this:

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

Also in your query you use the ExpressionWrapper on the Sum , instead you should use Sum on the ExpressionWrapper :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM