Commit ce25bba4 authored by Arnaud Fabre's avatar Arnaud Fabre

Optimizes sql queries

Adds a bit of denormalization (main_mandate) and adds select_related()
to query_set to reduce lazy loading in loops
parent 704fbd93
......@@ -29,10 +29,10 @@ class PhoneInline(admin.TabularInline):
class CountryInline(admin.TabularInline):
model = Country
extra = 0
class MemopolRepresentativeAdmin(admin.ModelAdmin):
list_display = ('full_name', 'country', 'score')
list_display = ('full_name', 'country', 'score', 'main_mandate')
search_fields = ('first_name', 'last_name', 'birth_place')
list_filter = ('gender', 'active')
inlines = [
......@@ -42,7 +42,8 @@ class MemopolRepresentativeAdmin(admin.ModelAdmin):
AdressInline,
]
# class MandateAdmin(admin.ModelAdmin):
# list_display = ('representative', 'group', 'role', 'constituency', 'begin_date', 'end_date', 'active')
# search_fields = ('representative', 'group', 'constituency')
......
......@@ -10,4 +10,4 @@ class Command(BaseCommand):
@transaction.atomic
def handle(self, *args, **options):
for representative in MemopolRepresentative.objects.all():
representative.update_country()
representative.update_all()
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('representatives', '0004_auto_20150709_1601'),
('legislature', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='memopolrepresentative',
name='main_mandate',
field=models.ForeignKey(default=True, to='representatives.Mandate', null=True),
),
]
......@@ -34,7 +34,8 @@ from core.utils import create_child_instance_from_parent
class MemopolRepresentative(Representative):
country = models.ForeignKey(Country, null=True)
score = models.IntegerField(default=0)
main_mandate = models.ForeignKey(Mandate, null=True, default=True)
def update_score(self):
score = 0
for vote in self.votes.all():
......@@ -71,11 +72,24 @@ class MemopolRepresentative(Representative):
code=country_mandate.group.abbreviation
)
self.country = country
self.save()
except ObjectDoesNotExist:
self.country = None
self.save()
self.save()
def update_main_mandate(self):
try:
self.main_mandate = self.mandates.get(
end_date__gte=datetime.now(),
group__kind='group'
)
except Mandate.DoesNotExist:
self.main_mandate = None
self.save()
def update_all(self):
self.update_country()
self.update_score()
self.update_main_mandate()
def active_mandates(self):
return self.mandates.filter(
......@@ -86,26 +100,15 @@ class MemopolRepresentative(Representative):
return self.mandates.filter(
end_date__lte=datetime.now()
)
def current_group_mandate(self):
return self.mandates.get(
end_date__gte=datetime.now(),
group__kind='group'
def votes_with_proposal(self):
return self.votes.select_related(
'proposal',
'proposal__recommendation'
)
@receiver(post_save, sender=Representative)
def create_memopolrepresentative_from_representative(instance, **kwargs):
memopol_representative = create_child_instance_from_parent(MemopolRepresentative, instance)
memopol_representative.update_country()
memopol_representative.save()
@receiver(post_save, sender=Mandate)
def update_memopolrepresentative_country(instance, created, **kwargs):
return
if not created:
return
# Update representative country
if instance.group.kind == 'country' and instance.representative.extra.country == None:
instance.representative.extra.update_country()
......@@ -4,10 +4,12 @@
- load by_group_url
- block content
%ul
%table.table
- for group in groups
%li
%a{'href': '{{ group | by_group_url }}'}
- if group.abbreviation
{{ group.abbreviation }} .
{{ group.name }}
%tr
%td
%a{'href': '{{ group | by_group_url }}'}w
- if group.abbreviation
={group.abbreviation}
%td
%a{'href': '{{ group | by_group_url }}'}= group.name
- load by_group_url
%td
%a{'href': "{% url 'legislature:representative_view_by_name' representative.full_name %}"}
%img{'src': '={representative.photo}', 'width': '80'}/
%td
%a{'href': "{% url 'legislature:representative_view_by_name' representative.full_name %}"}
={representative.full_name}
%td
%a{'href': "{% url 'legislature:representatives_by_group' group_kind='country' search=representative.country.code %}"}
={representative.country.name}
%td
%a{'href': "{{ representative.current_group_mandate|by_group_url }}"}
={representative.current_group_mandate.group.abbreviation}
......@@ -4,66 +4,51 @@
- load by_group_url
- block content
%p{:style => "float: left"}
%img{:src => "{{ representative.photo }}"}/
%h1= representative.full_name
%h2
SCORE : {{ representative.score }}
%p
%strong
%a{:href => "{{ representative.current_group_mandate|by_group_url }}"}
{{ representative.current_group_mandate.role }} of
{{ representative.current_group_mandate.group.name }}
%p
Born in {{ representative.birth_place }} the
{{ representative.birth_date }} ({{ representative.get_gender_display }})
%p= representative.country.name
-# Mandates
%div{:style => "clear: both"}
%h2 Votes
%ul
- for vote in representative.votes.all
%li
={vote.proposal.recommendation.title} -
={vote.position}
(recommendation: ={vote.proposal.recommendation.recommendation})
.representative
.row
.col-md-8
%h1.name
={representative.full_name}
%h2.score
SCORE : {{ representative.score }}
%p.group
%strong
%a{:href => "{{ representative.main_mandate|by_group_url }}"}
{{ representative.main_mandate.role }} of
{{ representative.main_mandate.group.name }}
%p.personal
Born in {{ representative.birth_place }} the
{{ representative.birth_date }} ({{ representative.get_gender_display }})
%p.country= representative.country.name
.col-md-4
%p.photo
%img{:src => "{{ representative.photo }}"}/
%h2 Mandates
- for mandate in representative.active_mandates
.mandate
%h3
{{ mandate.group.name }}
%small= mandate.role
%p
{{ mandate.begin_date }} to {{ mandate.end_date }} <br>
%a{:href => "{{ mandate|by_group_url }}"}
%strong {{ mandate.group.kind }} :
%em {{ mandate.group.name }} ({{ mandate.group.abbreviation }}) <br>
Constituency : {{ mandate.constituency.name }} <br>
%hr/
-# Former mandates
%h2{:style => "clear: both"} Former mandates
%h2 Votes
%table.table.votes
- for vote in representative.votes_with_proposal.all
%tr
%td= vote.proposal.recommendation.title
%td= vote.position
%td= vote.proposal.recommendation.recommendation
%td= vote.proposal.recommendation.weight
- for mandate in representative.former_mandates
.mandate
%h3
{{ mandate.group.name }}
%small= mandate.role
%p
{{ mandate.begin_date }} to {{ mandate.end_date }} <br>
%a{:href => "{{ mandate|by_group_url }}"}
%strong {{ mandate.group.kind }} :
%em {{ mandate.group.name }} ({{ mandate.group.abbreviation }}) <br>
Constituency : {{ mandate.constituency.name }} <br>
%hr/
%h2 Mandates
%table.table.mandates
- for mandate in representative.active_mandates
%tr.mandate
%td= mandate.role
%td
%a{:href => "{{ mandate|by_group_url }}"}
{{ mandate.group.name }} ({{ mandate.group.abbreviation }})
%td= mandate.begin_date
%td= mandate.end_date
%td= mandate.constituency.name
......@@ -5,11 +5,20 @@
- block content
- include 'legislature/search.html'
%p
Number of representatives: {{ object_count }}
%table
- include "core/blocks/pagination.html"
%table.table
%tr
%th
Photo
%th
Name
%th
Country
%th
Group
%th
Score
- for representative in object_list
%tr
%td
......@@ -25,8 +34,8 @@
={representative.country.name}
%td
%a{'href': "{{ representative.current_group_mandate|by_group_url }}"}
={representative.current_group_mandate.group.abbreviation}
%a{'href': "{{ representative.main_mandate|by_group_url }}"}
={representative.main_mandate.group.abbreviation}
%td
={representative.score}
......
......@@ -21,16 +21,21 @@
from __future__ import absolute_import
from datetime import datetime
from django.shortcuts import render
from django.db.models import Q
from django.shortcuts import render, get_object_or_404
from django.http import Http404
from ..models import MemopolRepresentative
from core.utils import render_paginate_list
def index(request, group_kind=None, group=None):
# Fetch active representatives
representative_list = MemopolRepresentative.objects.filter(
representative_list = MemopolRepresentative.objects.select_related(
'country',
'main_mandate',
'main_mandate__group',
).filter(
active=True
)
# Filter the list by group if group information is provided
......@@ -48,7 +53,7 @@ def index(request, group_kind=None, group=None):
mandates__group__kind=group_kind,
mandates__end_date__gte=datetime.now()
)
# Filter the list by search
representative_list = _filter_by_search(
request,
......@@ -59,23 +64,28 @@ def index(request, group_kind=None, group=None):
return render_paginate_list(
request,
representative_list,
'legislature/representative_index.html'
'legislature/representative_list.html'
)
def detail(request, pk=None, name=None):
if pk:
representative = get_object_or_404(
MemopolRepresentative,
id=pk
try:
query_set = MemopolRepresentative.objects.select_related(
'country',
'main_mandate'
)
elif name:
representative = get_object_or_404(
MemopolRepresentative,
slug=name
)
else:
if pk:
representative = query_set.get(
id=pk
)
elif name:
representative = query_set.get(
slug=name
)
else:
return Http404()
except MemopolRepresentative.DoesNotExist:
return Http404()
return render(
request,
'legislature/representative_detail.html',
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('votes', '0002_delete_memopolvote'),
]
operations = [
migrations.AlterModelOptions(
name='recommendation',
options={'ordering': ['proposal__datetime']},
),
]
......@@ -5,13 +5,13 @@
-# %p
Number of dossier: {{ object_count }}
%table
- for vote in object_list
%table.table
- for dossier in object_list
%tr
%td
%a{'href': "{% url 'votes:dossier_detail' pk=vote.id %}"}
{{ vote.name }}
-# %tr
-# - include '/representative_block.html'
%a{'href': "{% url 'votes:dossier_detail' pk=dossier.id %}"}
{{ dossier.name }}
%td= dossier.reference
%td= dossier.proposals.count
- include "core/blocks/pagination.html"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment