django listview order by model property
Question:
I have a model called Lap with a property calculated using data from the table
class Lap(models.Model):
team=models.ForeignKey('Team', models.DO_NOTHING)
timestamp=models.IntegerField()
num=models.IntegerField()
@property
def laptime(self):
endtime=self.timestamp
starttime=Lap.objects.get(team=self.team, num=self.num-1).timestamp)
return time.timedelta(seconds=endtime-starttime)
I am trying to create a listview for the model
class FastestLap(ListView):
model=Lap
template_name='fastestlaps.html'
context_object_name='laps'
I want to order the list view by the laptime property.
sorting by a column can be done using the ordering
variable or by creating a get_queryset
method and doing queryset.order_by(fieldname)
in that method but I cant find a way to order by the property. How do I order by laptime?
Answers:
Use Window
, F
and Lag
functions and annotate
so:
from django.db.models import Window, F
from django.db.models.functions import Lag
# from .models import Lap
# from django.views.generic import ListView
class FastestLap(ListView):
queryset = Lap.objects.annotate(
starttime=Window(
expression=Lag('timestamp', default=0),
partition_by=['team'],
order_by=F('num').asc(),
)
).annotate(
laptime=F('timestamp') - F('starttime')
).order_by('laptime')
template_name = 'fastestlaps.html'
context_object_name = 'laps'
References:
I have a model called Lap with a property calculated using data from the table
class Lap(models.Model):
team=models.ForeignKey('Team', models.DO_NOTHING)
timestamp=models.IntegerField()
num=models.IntegerField()
@property
def laptime(self):
endtime=self.timestamp
starttime=Lap.objects.get(team=self.team, num=self.num-1).timestamp)
return time.timedelta(seconds=endtime-starttime)
I am trying to create a listview for the model
class FastestLap(ListView):
model=Lap
template_name='fastestlaps.html'
context_object_name='laps'
I want to order the list view by the laptime property.
sorting by a column can be done using the ordering
variable or by creating a get_queryset
method and doing queryset.order_by(fieldname)
in that method but I cant find a way to order by the property. How do I order by laptime?
Use Window
, F
and Lag
functions and annotate
so:
from django.db.models import Window, F
from django.db.models.functions import Lag
# from .models import Lap
# from django.views.generic import ListView
class FastestLap(ListView):
queryset = Lap.objects.annotate(
starttime=Window(
expression=Lag('timestamp', default=0),
partition_by=['team'],
order_by=F('num').asc(),
)
).annotate(
laptime=F('timestamp') - F('starttime')
).order_by('laptime')
template_name = 'fastestlaps.html'
context_object_name = 'laps'