# Django how to make this view faster?

I have view and it works correct, but very slow

class Reading(models.Model):
meter = models.ForeignKey(Meter, verbose_name=_('meter'))
date = models.DateTimeField(verbose_name=_('date'))

class Meta:
get_latest_by = 'date'
ordering = ['-date', ]

def __unicode__(self):
return u'%s' % (self.date,)

@property
def consumption(self):
try:
end = self.get_next_by_date(code=self.code, meter=self.meter)
except:
return 0.0

@property
def middle_consumption(self):
data = []
current_year = self.date.year
for year in range(current_year - 3, current_year):
date = datetime.date(year, self.date.month, self.date.day)
try:
date = date,
meter = self.meter,
code = self.code
).consumption)
except:
data.append(0.0)
for i in data:
if not i:
data.pop(0)
return sum(data) / len(data)

class DataForDayChart(TemplateView):
def get(self, request, *args, **kwargs):
output = []
meter = Meter.objects.get(slug=kwargs['slug'])
# TODO: Make it faster
output.append({
})
return HttpResponse(output, mimetype='application/json')


What should I change to make it faster?

-
How slow it is? How many records the view returns? Looks like you have a loots of SQL Queries there, try to reduce amount of queries. –  srusskih Dec 24 '12 at 8:18

There's nothing intrinsically time-consuming here code-wise - I think the best approach is to make sure that your database tables are set up correctly with the required indices. Perhaps create a view on the db to push some work onto that rather than select in code?

I am a little puzzled however by your middle_consumption function. The inner loop contents do something like:

get a date, x years ago from present day
get a reading on that date, or 0 on failure
go through the results
if the current item is 0, delete the **first** item


This seems wrong.

1. What happens on February 29th? It would be better to add 365 days if that's appropriate for your application.
2. Why add a value only to (presumably want to) delete it again? Would something like this be better?

try: