Cumulative Total in html table displayed next to each entry

Hi, I’m new to Django and Python and have been plugging through Python Crash Course. I have finished that and now have been making my own Django project, adding some extra bits in.

Currently, I have a table of entries from my model which I am displaying with a template, each entry in the table has a time and some other data. What I would like is the value for the cumulative time in a column, next to each entries time ie

Lesson | Lesson time |cumulative time

Lesson 1 | 0.5 | 0.5
lesson 2 | 1 | 1.5
lesson3 | 1.3 | 2.8

I’m just really stuck on how to get this done, have looked at lot’s of stack overflow and tried various ways that I just can’t get to work correctly. Looking at other examples they use annotate() and cumsum, but I’ve not been able to get that to work. I’ve done count and sum of other values but this has got me stuck.

my model
class Lessontopic(models.Model):
“”“The topic of each lesson “””
text= models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
public = models.BooleanField(default=False, verbose_name=“Make post public?”,
help_text=“click on this form if you want it to be viewed by anyone”)
lesson_number = models.PositiveIntegerField(blank=True, null=True)
lesson_time = models.DecimalField(‘enter lesson time’, max_digits=2, decimal_places=1)

Hoping somebody maybe able to point me in the right direction as to how to sort this as I must be making it harder than it is.

Also, first post so apologies if this isn’t the right place to ask or I have not included enough information.

Many thanks

What you’re looking for here are the Window functions. Also see the Postgresql docs for Window functions. Also see this blog post for a sample.

Hi Ken, thanks for taking the time to help. So, I’ve had a read up and a lot is way above my understanding. I am trying to construct something like this below. Is that along the right lines? I still can’t get it to work and currently out of skill and ideas.

cumulative_time = Lessontopic.objects.annotate(
cumulative_times=Window(Sum(‘lesson_time’),
order_by=F(‘date_added’).asc()
total_times = Lead(expression = ‘cumulative_amount’, offset=1, default=0)))

Using the code as above I just get Traceback. If I remove the total_times row. I then get a “near “OVER”: syntax error”.

Any advice greatly appreciated.Preformatted text

Try this:

cumulative_time = Lessontopic.objects.annotate(
    cumulative_times=Window(
        expression = Sum('lesson_time'),
        order_by=F('date_added').asc(),
        frame=RowRange(start=None, end=0)
    )
)

Also, when posting code here, please remember to enclose it between lines of three backtick - ` characters. (The lines immediately before and after the snippet above are ```)

Hi Ken, Many thanks again for taking the time to help.

I’m still running into problems with this, Im getting cumulative_time Error in formatting: OperationalError: near "OVER": syntax error

I removed it from the context and tried just calling print(cumulative_time) and it’s still throwing the above error.

When I have a context ‘cumulative time’: cumulative_time in the context and template calling {{cumulative_time}} I am getting Error during Template Rendering, error at line 35 this time, has also been 0.
35 <span class="navbar-text">Hello, {{ user.username }}.</span>

This was working fine before trying to add the cumulative_times

I had a look on SO and similar problems people had were with the version of sqlite3. I’ve tried checking, currently I have installed python 3.8.2. I have sqlite3 version 3.28.0 installed also.

First, when reporting errors, it’s usually quite helpful to post the entire traceback. There’s a lot of context missing when you just try to summarize the issue.

Now, from what I can see:

This is invalid. It’s not appropriate to have a context key with a space in it when being rendered.

Also:

This isn’t going to work since you don’t have a value associated in your context with that key.

Hi, apologies, the cumulative time was an error on my part in the post. In the view it is correctly attributed as
'cumulative_time':cumulative_time,

Here is the full traceback.

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/topics

Django Version: 3.1.7
Python Version: 3.8.2
Installed Applications:
['flying_logs',
 'users',
 'bootstrap4',
 'django_extensions',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /Users/pq/Desktop/program_course/flying/flying_logs/templates/flying_logs/base.html, error at line 35
   near "OVER": syntax error
   25 : 			<span class="navbar-toggler-icon"></span></button>
   26 : 		<div class="collapse navbar-collapse" id="navbarCollapse">
   27 : 			<ul class="navbar-nav mr-auto">
   28 : 				<li class="nav-item">
   29 : 					<a class="nav-link" href="{% url 'flying_logs:topics' %}">
   30 : 						Topics</a></li>
   31 : 			</ul>
   32 : 			<ul class="navbar-nav ml-auto">
   33 : 				{% if user.is_authenticated %}
   34 : 					<li class="nav-item">
   35 : 						<span class="navbar- text">He llo, {{ user.username }}.</span>
   36 : 					</li>
   37 : 					<li class="nav-item">
   38 : 						<a class="nav-link" href="{% url 'users:logout' %}">Log out</a>
   39 : 					</li>
   40 : 				{% else %}
   41 : 					<li class="nav-item">
   42 : 						<a class="nav-link" href="{% url 'users:register' %}">Register</a>
   43 : 					</li>
   44 : 					<li class="nav-item">
   45 : 						<a class="nav-link" href="{% url 'users:login' %}">Log in</a></li>


Traceback (most recent call last):
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute
    return Database.Cursor.execute(self, query, params)

The above exception (near "OVER": syntax error) was the direct cause of the following exception:
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/pq/Desktop/program_course/flying/flying_logs/views.py", line 194, in topics
    return render(request, 'flying_logs/topics.html', context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/shortcuts.py", line 19, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 170, in render
    return self._render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/loader_tags.py", line 150, in render
    return compiled_parent._render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 162, in _render
    return self.nodelist.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 938, in render
    bit = node.render_annotated(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/defaulttags.py", line 211, in render
    nodelist.append(node.render_annotated(context))
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 905, in render_annotated
    return self.render(context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 994, in render
    return render_value_in_context(output, context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/template/base.py", line 973, in render_value_in_context
    value = str(value)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/models/query.py", line 263, in __repr__
    data = list(self[:REPR_OUTPUT_SIZE + 1])
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/models/query.py", line 269, in __len__
    self._fetch_all()
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/models/query.py", line 1308, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/models/query.py", line 53, in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1156, in execute_sql
    cursor.execute(sql, params)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/Users/pq/Desktop/program_course/flying/fl_env/lib/python3.8/site-packages/django/db/backends/sqlite3/base.py", line 413, in execute
    return Database.Cursor.execute(self, query, params)

Exception Type: OperationalError at /topics
Exception Value: near "OVER": syntax error

I notice the line that is throwing the error in traceback view has some additional spaces, in the template these aren’t present. In my template line 35
<span class="navbar-text">Hello, {{ user.username }}.</span>

It’s quite likely that the error is not occurring on the line identified by the traceback. (I don’t know enough about the template system to understand why, or how to fully take advantage of the information provided when diagnosing issues in templates.)

I think it might be helpful if you post the template where you’re rendering that cumulative_time field, and quite possibly helpful if you post the complete view where this data is all being gathered.

Hi, here is the template that is trying to render the cumulative_time. It is in line 32 inside the for loop.
I’m afraid it is all very much a work in progress, so a lot of print statements and not terribly succinct. Been trying to learn to code and thought try and add some extra features to what I leant in the Crash Course Book. Thanks again for taking the time to help.

below is topics.html

{% extends "flying_logs/base.html" %}
  <h1>Topics</h1>
{% block page_header %}
	{% endblock page_header %}	

{% block content %}

<div class="container">

    <table class="table text-center  table-hover table-bordered" >
        
    <tr><tr class="table-primary">
      <th style="width: 10%">Lesson No.</th>
      <th scope="col">Date</th>
      <th scope="col">Lesson</th>
      <th scope="col">Dual/Solo
      <th scope="col">Flying time</th>
      <th scope="col">Cumulative</th>
    </tr>
  </thead>

        {% for topic in topics %}

        	{% if topic.solo_lesson %} 
            <tr class="table-success">
            	{% endif %}        	
            	<td class="text-center"> {{topic.lesson_number}}</td>
                <td>{{ topic.date|date:'d/m/Y'}}</td>
                <td><a href="{% url 'flying_logs:topic' topic.id %}">{{ topic }}</a></td>
                <td>{{ topic.solo_lesson|yesno:"Solo, Dual"  }}</td>
                <td class="text-center">{{topic.lesson_time}}</td>
                <td>Time so far{{ cumulative_time }}</td>
            </tr>
        {% endfor %}</table>
        
</div>

<div class="container">
    <table class="table text-center table-hover table-bordered" >
    <thread>    
    <tr><tr class="table-primary">
      
      <th style="width: 5%">Solo</th>
      <th style="width: 20%">Dual</th>
      <th style="width: 20%">total time</th>
      <th style="width: 20%">Time remaing</th>
      <th style="width: 20%"> Solo Lessons</th>
      <th style="width: 35%">Number of lessons</th>

           
    </tr>
  </thead>
     
      	<td>{{solo_time|floatformat:1}}</td>
          <td>{{dual_time|floatformat:1}}</td>
          <td>{{time}}</td>

          {% if remaining_time >= 0 %} 
     		<td class="table-danger">{{ remaining_time|floatformat:1 }}</td>
 		 	{% elif remaining_time <= 0 %}
 		 	<td class="table-success">You've done the minimum hours!!</td>
 	

     		{% endif %}
          <td class="text-center"> {{ solo_num}} </td>
          <td>{{lessons}}</td>

      </tr>
      </tr>
      
      </table>
      </div>



	
	<h3><a href="{% url 'flying_logs:new_topic' %}"><button name="new entry"
		class="btn btn-primary">Add a new topic</button></a></h3>

{% if graph %}
<div style="width:600;height:500">
{{ graph|safe }}
</div>
{% endif %}


{% endblock content %}		

Below is base.html

{% load bootstrap4 %}

<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1,
		shrink-to-fit=no">
	<title>Flying Log</title>

	{% bootstrap_css %}
	{% bootstrap_javascript jquery='full' %}

</head>
<body>

	<nav class="navbar navbar-expand-md navbar-light bg-light mb-4 border">
		
		<a class="navbar-brand" href="{% url 'flying_logs:index' %}">
			Flying logs</a>

		<button class="navbar-toggler" type="button" data-toggle="collapse"
				data-target="#navbarCollapse" aria-controls="navbarCollapse"
				aria-expanded="false" aria-label="Toggle navigation">
			<span class="navbar-toggler-icon"></span></button>
		<div class="collapse navbar-collapse" id="navbarCollapse">
			<ul class="navbar-nav mr-auto">
				<li class="nav-item">
					<a class="nav-link" href="{% url 'flying_logs:topics' %}">
						Topics</a></li>
			</ul>
			<ul class="navbar-nav ml-auto">
				{% if user.is_authenticated %}
					<li class="nav-item">
						<span class="navbar-text">Hello, {{ user.username }}.</span>
					</li>
					<li class="nav-item">
						<a class="nav-link" href="{% url 'users:logout' %}">Log out</a>
					</li>
				{% else %}
					<li class="nav-item">
						<a class="nav-link" href="{% url 'users:register' %}">Register</a>
					</li>
					<li class="nav-item">
						<a class="nav-link" href="{% url 'users:login' %}">Log in</a></li>
				{% endif %}		
			</ul>
		</div>

	</nav>

	<main role="main" class="container">
		<div class="pb-2 mb-2 border-bottom">
			{% block page_header %}{% endblock page_header %}
		</div>
		<div>
			{% block content %}{% endblock content %}				
		</div>
	</main>

</body>

</html>

Here is the view.py

from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import render, redirect, get_object_or_404
from django.db.models import Q
from django.db.models import Sum
import json
import requests 
import math
from datetime import date, time, datetime

from plotly.graph_objs import Bar, Layout, Pie
from plotly import offline

from .models import Lessontopic, Entry
from .forms import TopicForm, EntryForm


from django.conf import settings
from django.core.mail import send_mail

from django.db.models import Window, Sum, F, RowRange
from django.db.models.functions import Lead


# Create your views here.

def check_topic_owner(request, topic):
	if topic.owner != request.user:
		raise Http404

def _get_topics_for_user(user):
    """ returns a queryset of topics the user can access """
    q = Q(public=True)
    if user.is_authenticated:
       # adds user's own private topics to the query
       q = q | Q(public=False, owner=user)

    return Lessontopic.objects.filter(q)

def get_current_weather(request):

	url = ('https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/taurangaaerodrome/today?unitGroup=metric&key=MZRCJUSM7DG5Z3TE8FPVNR4E4')
	r = requests.get(url)
	print(f'status code is {r.status_code}')

	response_dict = r.json()
	repo_dicts = response_dict['currentConditions']
	repo_dict = repo_dicts['datetime'], repo_dicts['temp']
	current_temp = repo_dicts['temp']
	return response_dict

def last_lesson(request):
	latest = Lessontopic.objects.latest('date')
	latest_lesson = Lessontopic.objects.get(id=latest.id)
	return latest_lesson	




#@login_required
def index(request):
	"""The home page for flying journal"""
	the_last_lesson = last_lesson(request)
	l_lesson_date = the_last_lesson.date.date()
	x = the_last_lesson.date.time()
	print( 'll', x)
	print('\n  time now:', datetime.now(),'\n')

	days_since_last = str(datetime.now().date() - l_lesson_date)[:7]
	abc = datetime.now().date()
	print(abc)
	print((days_since_last))
	
	print('\nDAYS SINCE LAST LESSON', str(days_since_last))
	print('CURRENRT',datetime.now())


	time = Lessontopic.objects.aggregate(Sum('lesson_time'))
	print('AAAAAA',time)
	total_time = time.get('lesson_time__sum')
	print('BBBBBBB', total_time)
	total_time = float(total_time)
	print(F'total flying time{total_time} hours')
	lessons = Lessontopic.objects.all().count()
	print(f"There has been {lessons} lessons ")
	solo = (Lessontopic.objects.filter(solo_lesson=True)
		.aggregate(Sum('lesson_time')))
	solo_time = float(solo.get('lesson_time__sum'))
	print(f"solo lesson flying time {solo_time} hours")
	solo_num = Lessontopic.objects.filter(solo_lesson=True).all().count()
	print(f'ther have been {solo_num} solo lessons')
	
	get_weather = get_current_weather(request)
	weather = get_weather['currentConditions']
	future = get_weather['days']
	ft = future[0]
	forecast_max = ft['tempmax']	
	issue_time = weather['datetime']
	current_temp = weather['temp']
	wind_speed =  weather['windspeed']
	wind_direction = int(weather['winddir'])
	current_conditions = weather['conditions']

		
	context = {'time':total_time, 'lessons':lessons, 'solo_time':solo_time,
				'solo_num':solo_num, 'weather':weather, 'current_temp':current_temp,
				'issue_time':issue_time, 'wind_speed':wind_speed,
				'wind_direction':wind_direction, 'current_conditions':current_conditions,
				'forecast_max': forecast_max, 'the_last_lesson':the_last_lesson,
				'days_since_last':days_since_last,}
	#ModelName.objects.filter(field_name__isnull=True).aggregate(Sum('field_name'))
	#print('hll')
	return render(request, 'flying_logs/index.html', context)


#@login_required
def topics(request):
	"""Show all the topics"""
	
	# Get the public topics 
	public_topics = Lessontopic.objects.filter(public=True).order_by('date_added')
	# Get the private topics
	if request.user.is_authenticated:
		private_topics = Lessontopic.objects.filter(owner=request.user).order_by('date_added')
		topics =  private_topics
		"""By Adding private into topics, seeing all public topics not just users
		this way any topic added by authenticated user comes up in private, even if
		it is also visible in public"""

		time = Lessontopic.objects.aggregate(Sum('lesson_time'))
		total_time = time.get('lesson_time__sum')
		total_time = float(total_time)
		lessons = Lessontopic.objects.all().count()
		print(f"There has been {lessons} lessons ")
		solo = (Lessontopic.objects.filter(solo_lesson=True)
			.aggregate(Sum('lesson_time')))
		solo_time = solo.get('lesson_time__sum')
		print(f"solo lesson flying time {solo_time} hours")
		solo_num = Lessontopic.objects.filter(solo_lesson=True).all().count()
		dual = (Lessontopic.objects.filter(solo_lesson=False)
			.aggregate(Sum('lesson_time')))
		dual_time = dual.get('lesson_time__sum')
		remaining_time = 50 - total_time	
		
		#Make a pie chart.
		labels = ['Solo', 'Dual']
		values = [solo_time, dual_time]
		chat = ['this is long']
		# Visualise the results
		data=[Pie(labels=labels,text=chat,values=values,pull=[0.1, 0],
			textposition='outside')
			]

		x_axis_config = {'title': 'Hours'}
		y_axis_config = {'title': 'Lesson type'}
		my_layout = Layout(title='Flying time Solo vs Dual Instruction',title_font_color='black'	,
				title_font_size=30, title_x=0.5, legend_bordercolor='green', legend_borderwidth=5	)
		fig = ({'data': data, 'layout': my_layout})
		div = offline.plot(fig, auto_open=False, output_type='div')

		cumulative_time = Lessontopic.objects.annotate(
						    cumulative_times=Window(
					        expression = Sum('lesson_time'),
					        order_by=F('date_added').asc(),
					        frame=RowRange(start=None, end=0)
					    	)
						)

		context = {'topics': topics, 'cumulative_time':cumulative_time,'lessons':lessons, 'solo_time':solo_time,
				'solo_num':solo_num, 'dual_time':dual_time,'solo_num':solo_num,
				'remaining_time':remaining_time, 'dual':dual,'graph':div,}


	else:
		topics = public_topics
		context = {'topics': topics}

	return render(request, 'flying_logs/topics.html', context)

#@login_required
def topic(request, topic_id):
	"""Shpw a single topic and the entries associated with it"""
	topics = _get_topics_for_user(request.user)
	topic = get_object_or_404(topics, id=topic_id)
	# Make sure the topic belongs to the current user.
	#check_topic_owner(request, topic)

	rd = topic.runway_direction
	x = (str(topic.date)[:10])
	#y = datetime.strptime(x, "%Y-%m-%d")
	#print(y)
	start_time = topic.time_of_lesson 
	if start_time < 10:
		start_time = '0'+str(start_time)
	else: start_time = str(start_time)
			
	time = int(start_time) - 3 
	if time < 10 :
		time = '0'+str(time)
	else: time = str(time)	
	print('heres time:',time)
	end_time = str(int(start_time) + 2)
	
	#(type(time))
	#('end timme:', end_time)
	#(x)
	date1 = x
	#(date1)
	# Removed the +13 as will fail once clocks chage= just checking to 20
	date_string= date1 +'T'+str(start_time)+':00:00+'
	#('...............',date_string)
	#(date_string[20:])
	
	url = ('https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/weatherdata/history?aggregateHours=1&combinationMethod=aggregate&startDateTime='+ date1 +'T'+ time + '%3A00%3A00&endDateTime='+ date1 +'T' + end_time +'%3A00%3A00&maxStations=-1&maxDistance=-1&contentType=json&unitGroup=metric&locationMode=single&key=MZRCJUSM7DG5Z3TE8FPVNR4E4&locations=tauranga')
	r = requests.get(url)
	#(f'status code is {r.status_code}')
	response_dict = r.json()
	repo_dicts = response_dict['location']
	repo_dict = repo_dicts['values']
	values = repo_dict
	day_0 = values[0]
	day_1 = values[1]

	for x in values:
		if x['datetimeStr'][:20] == date_string:
			print('they match',x['datetimeStr'][:20],date_string)
			day = x
			break	

		elif x['datetimeStr'][:20] != date_string:
			print('they dont match',x['datetimeStr'],date_string)	


	time_of_forecast = str(day['datetimeStr'][11:16])
	print('forecast time',time_of_forecast)
	temp = day['maxt']
	wind = day['wspd']
	knots = (wind*0.54)
	knots = "{:.2f}".format(knots)
	conditions = day['conditions']
	wind_direction = int(day['wdir'])

	#Calculate the crosswind
	if wind_direction > rd:
		angle = wind_direction - rd
		print(angle, 'is the angle dir - rd')
		print('radians',math.sin(math.radians(angle)))
		print('normal', math.sin(angle))
		print(math.sin(math.radians(90)))
		print(math.sin(math.radians(30)))
	else:
		angle = rd - wind_direction
		print(angle, ' is from rd - dir')
		
	crosswind = ((math.sin(math.radians(angle))*wind)*(0.54))
	crosswind_knots = "{:.2f}".format(crosswind)
	print('the crosswind is:',crosswind)	
	print(conditions)
	print('the temp ===',temp)
	
	#t1 = Lessontopic.objects.get(temp)


	entries = topic.entry_set.order_by('-date_added')	
	context = {'topic': topic, 'entries': entries, 'topics': topics, 'temp':temp,
				'wind':wind, 'conditions':conditions,'wind_direction':wind_direction,
				'rd':rd, 'knots':knots, 'crosswind_knots':crosswind_knots,
				'time_of_forecast':time_of_forecast,
				}
	return render(request, 'flying_logs/topic.html', context)

@login_required
def new_topic(request):
	"""Add a new topic."""
	if request.method != 'POST'	:
		# No data submitted create a new blank form.
		form = TopicForm()
	else:
		# POST data submitted; process the data.
		form = TopicForm(data=request.POST)
		if form.is_valid():
			new_topic = form.save(commit=False)
			new_topic.owner = request.user
			new_topic.adding = 'does this work?'
			new_topic.save()
			return redirect ('flying_logs:topics')



		# Dispalay a blank or invalid form.
	context = {'form': form}
	return render(request, 'flying_logs/new_topic.html', context)


@login_required
def new_entry(request, topic_id):
	""" Add a new entry for a particualr topic"""
	topic = get_object_or_404(Lessontopic, id=topic_id)

	if request.method != 'POST':
		# No data submitted; create a blank form
		form = EntryForm()
	else:
		# POST data submitted; process the data.
		form = EntryForm(data=request.POST)	
		if form.is_valid():
			new_entry = form.save(commit=False)
			new_entry.blahtopic = topic
			new_entry.save()
			return redirect('flying_logs:topic', topic_id=topic_id)

	

	# Display a blank or invalid form.
	context = {'topic':topic, 'form':form}
	return render(request, 'flying_logs/new_entry.html', context)

#@login_required
def edit_entry(request, entry_id):
	"""Edit an existing extry"""
	entry = Entry.objects.get(id=entry_id)
	topic = entry.blahtopic
	check_topic_owner(request, topic)
	

	if request.method != 'POST':
		# Initial request; prefill the current form with current entry.
		form = EntryForm(instance=entry)
	else:
		# POST data submitted; process the data
		form = EntryForm(instance=entry, data=request.POST)
		if form.is_valid():
			form.save()
			return redirect('flying_logs:topic', topic_id=topic.id)

	context = {'entry': entry, 'topic':topic, 'form':form}
	return render(request, 'flying_logs/edit_entry.html', context)			

In case it helps this is my models.py file.

from django.db import models
from django.contrib.auth.models import User
from django.forms.widgets import DateInput 
from django import forms
import json
import requests 

# Create your models here.

class Lessontopic(models.Model):
	"""The topic of each lesson or day flying"""
	text= models.CharField(max_length=200)
	date_added = models.DateTimeField(auto_now_add=True)
	owner = models.ForeignKey(User, on_delete=models.CASCADE)
	public = models.BooleanField(default=False, verbose_name="Make post public?",
		help_text="click on this form if you want it to be viewed by anyone")
	lesson_number =  models.PositiveIntegerField(blank=True, null=True)
	lesson_time = models.DecimalField('enter flight time', max_digits=2, decimal_places=1)
	solo_lesson = models.BooleanField(default=False, verbose_name="Were you  solo for the lesson",
			help_text="Click if were flying solo for the lesson")
	runway_direction = models.PositiveIntegerField(
			 verbose_name="Select runway direction: 07 or 25")
	number_landings = models.PositiveIntegerField(blank=True, default=1,
							help_text="Enter how many landings")


	date = models.DateTimeField()

	time_of_lesson = models.PositiveIntegerField(
			 verbose_name="time that the lesson started")

	weather_data = models.CharField(max_length=200)
	adding = models.TextField(default=None, null=True, blank=True)

	def __str__(self):
		"""Return a string representation of the modeel"""
		return self.text

	
	 
	
	

class Entry(models.Model):
	"""Describe the lesson and add extra information"""
	blahtopic = models.ForeignKey(Lessontopic, on_delete=models.CASCADE)
	text = models.TextField()
	to_improve = models.TextField()
	date_added = models.DateTimeField(auto_now_add=True)

	class Meta:
		verbose_name_plural = 'entries'

	def __str__(self):
		"""Return a string representation of the model."""
		if len(self.text) > 50 : 
			return f"{self.text[:50]}..."	
		else:	
			return f"{self.text}"

Ok, The cumulative_time that you are adding to the context is a queryset of Lessontopic objects. You’re trying to render a complete queryset each time through your for loop.
You’ve got nothing that associates an instance of Lessontopic with the topic being iterated over.

I was having a play around this morning and came to the same conclusion, like you say it is just a whole queryset.
But I’m still unsure how to go about getting the cumulative time in the table. I tried just doing a simple for loop as you would in pyhton, setting cumulative time to 0 and adding lesson time to it each time through the loop and that doesn’t work. So I need to try and find a way of having the time from each lesson added to the previous lessons cumulative_time, which is what I am stuck on.

Instead of creating a separate queryset, perform the annotation in the queryset that you are using to create the iterable you’re using to render in your template.

The trouble is, I’m not sure how to go about creating the iterable for my template. I know going to need to reference the id and a counting loop, I’ve tried doing it, but I don’t know how to go about doing it properly.

You’re already doing it, here:

Your template is iterating over the individual entries in topics. Isn’t this the list where you want the cumulative time for each entry? (That’s the intent I’m getting from where you’re attempting to display it within your template.)