Есть несколько таблиц. Проект уже написан, все работает замечательно, но вот нужно вывести таблицу с данными различными, и из различных таблиц. Предпринимал попытки все это написать одним ORM запросом, потом SQL, в итоге решил собрать все данные во views и выдать на рендеринг в шаблон.
Вот таблицы:
class Contest(models.Model):
title = models.CharField(max_length=255)
slug = models.CharField(max_length=50)
date_start = models.DateTimeField(_("Date Start"), null=True, blank=True)
date_end = models.DateTimeField(_("Date End"), null=True, blank=True)
class Element(models.Model):
contest = models.ForeignKey(Contest, blank=True, null=True)
title = models.CharField(max_length=255)
weight = models.IntegerField(_('Weight'), blank=True, default=1)
class UserActiv(models.Model):
user = models.ForeignKey(User)
contest = models.ForeignKey(Contest)
date_activation = models.DateTimeField(_("Activation Date"), auto_now_add=True)
class Data(models.Model):
useractive = models.ForeignKey(UserActiv)
element = models.ForeignKey(Element, blank=True, null=True)
date_review = models.DateTimeField(_("Date Review"), auto_now_add=True)
showing = models.IntegerField(_('Showing'), blank=True, default=0)
Вот так, как мне кажется не правильно, собираю данные:
...
active_contest = get_object_or_404(Contest, slug = slug)
table_users = []
header_table = []
for element in Element.objects.filter(contest = active_contest):
header_table.append(element.title)
for user in UserActiv.objects.filter(contest = active_contest):
tmp_user = {}
tmp_user.update({
'username': get_object_or_none(User, id = user.user.id).username
})
element_value = []
for el in Element.objects.filter(contest = active_contest):
element_value.append(Data.objects.filter(showing=2, useractive=user.id, element = el.id).count())
tmp_user.update({
'el': element_value
})
tmp_user.update(
Element.objects.filter(data__showing=2, data__useractive=user.id).aggregate(sum_weight=Sum('weight'))
)
try:
tmp_user.update({
'last_date_find_element': Data.objects.filter(showing=2, useractive=user.id).order_by('-date_review')[:1].get().date_review
})
except:
tmp_user.update({
'last_date_find_element': None
})
table_users.append(tmp_user)
render_dict.update({
'table_users': table_users,
'header_table': header_table
})
return render_to_response('contest_users.html', render_dict,
context_instance=RequestContext(request))
В итоге я получаю
- список полей в заголовок (так как там может быть различное количество из таблицы Element)
- ник юзера из главной таблицы User
- количество вхождений каждого элемента из Element
- общую сумму всех вхождений по весу из Element
- дату последней записи в Data
Подозреваю что хоть реализация и грязная, производительность стремится вниз, но как по другому собрать все данные не приходит в голову.
Может будут у кого идеи.