From c85418c1d887da9f2949eedd9479b6f6861b4031 Mon Sep 17 00:00:00 2001 From: Nicolas Joyard <joyard.nicolas@gmail.com> Date: Sun, 15 May 2016 08:51:07 +0200 Subject: [PATCH] Add DossierScore view model, publish in API --- memopol/api.py | 2 + representatives_recommendations/api.py | 24 ++++++++++ .../migrations/0002_dossierscore.py | 47 +++++++++++++++++++ representatives_recommendations/models.py | 12 +++++ .../serializers.py | 8 ++++ 5 files changed, 93 insertions(+) create mode 100644 representatives_recommendations/migrations/0002_dossierscore.py diff --git a/memopol/api.py b/memopol/api.py index 6a1fd863..2986d2af 100644 --- a/memopol/api.py +++ b/memopol/api.py @@ -14,6 +14,7 @@ from representatives_votes.api import ( ) from representatives_recommendations.api import ( + DossierScoreViewSet, RecommendationViewSet, RepresentativeScoreViewSet, ScoredVoteViewSet @@ -24,6 +25,7 @@ router = routers.DefaultRouter() router.register(r'constituencies', ConstituencyViewSet) router.register(r'dossiers', DossierViewSet) +router.register(r'dossier_scores', DossierScoreViewSet) router.register(r'groups', GroupViewSet) router.register(r'mandates', MandateViewSet) router.register(r'proposals', ProposalViewSet) diff --git a/representatives_recommendations/api.py b/representatives_recommendations/api.py index 3ca026b7..8b4fa191 100644 --- a/representatives_recommendations/api.py +++ b/representatives_recommendations/api.py @@ -6,18 +6,42 @@ from rest_framework import ( from representatives.api import DefaultWebPagination from .models import ( + DossierScore, Recommendation, RepresentativeScore, ScoredVote ) from .serializers import ( + DossierScoreSerializer, RecommendationSerializer, RepresentativeScoreSerializer, ScoredVoteSerializer ) +class DossierScoreViewSet(viewsets.ReadOnlyModelViewSet): + """ + API endpoint to view representative score contribution for each dossier + """ + queryset = DossierScore.objects.all() + filter_backends = ( + filters.DjangoFilterBackend, + filters.SearchFilter, + filters.OrderingFilter + ) + filter_fields = { + 'id': ['exact'], + 'dossier': ['exact'], + 'representative': ['exact'], + 'score': ['exact', 'gte', 'lte'] + } + search_fields = ('dossier', 'representative') + ordering_fields = ('representative', 'dossier') + pagination_class = DefaultWebPagination + serializer_class = DossierScoreSerializer + + class RecommendationViewSet(viewsets.ReadOnlyModelViewSet): """ API endpoint that allows recommendations to be viewed. diff --git a/representatives_recommendations/migrations/0002_dossierscore.py b/representatives_recommendations/migrations/0002_dossierscore.py new file mode 100644 index 00000000..72ebd2cd --- /dev/null +++ b/representatives_recommendations/migrations/0002_dossierscore.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('representatives_recommendations', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='DossierScore', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('score', models.IntegerField(default=0)), + ], + options={ + 'db_table': 'representatives_recommendations_dossierscores', + 'managed': False, + }, + ), + migrations.RunSQL( + """ + CREATE VIEW "representatives_recommendations_dossierscores" + AS SELECT + "representatives_votes_vote"."representative_id" || ':' || "representatives_votes_proposal"."dossier_id" AS "id", + "representatives_votes_vote"."representative_id", + "representatives_votes_proposal"."dossier_id", + SUM(CASE WHEN "representatives_votes_vote"."position" = ("representatives_recommendations_recommendation"."recommendation") + THEN "representatives_recommendations_recommendation"."weight" + ELSE (0 - "representatives_recommendations_recommendation"."weight") + END) AS "score" + FROM "representatives_votes_vote" + INNER JOIN "representatives_votes_proposal" + ON ( "representatives_votes_vote"."proposal_id" = "representatives_votes_proposal"."id" ) + LEFT OUTER JOIN "representatives_recommendations_recommendation" + ON ( "representatives_votes_proposal"."id" = "representatives_recommendations_recommendation"."proposal_id" ) + WHERE "representatives_recommendations_recommendation"."id" IS NOT NULL + GROUP BY + "representatives_votes_vote"."representative_id", + "representatives_votes_proposal"."dossier_id" + """ + ), + ] diff --git a/representatives_recommendations/models.py b/representatives_recommendations/models.py index 3f92d639..49a6ecf5 100644 --- a/representatives_recommendations/models.py +++ b/representatives_recommendations/models.py @@ -11,6 +11,18 @@ from representatives_votes.models import Dossier, Proposal, Vote from representatives.models import Representative +class DossierScore(models.Model): + id = models.CharField(max_length=255, primary_key=True) + representative = models.ForeignKey(Representative, + on_delete=models.DO_NOTHING) + dossier = models.ForeignKey(Dossier, on_delete=models.DO_NOTHING) + score = models.IntegerField(default=0) + + class Meta: + managed = False + db_table = 'representatives_recommendations_dossierscores' + + class RepresentativeScore(models.Model): representative = models.OneToOneField('representatives.representative', primary_key=True, related_name='score') diff --git a/representatives_recommendations/serializers.py b/representatives_recommendations/serializers.py index df42c26e..4a1ae0d0 100644 --- a/representatives_recommendations/serializers.py +++ b/representatives_recommendations/serializers.py @@ -1,12 +1,20 @@ from rest_framework import serializers from .models import ( + DossierScore, Recommendation, RepresentativeScore, ScoredVote ) +class DossierScoreSerializer(serializers.HyperlinkedModelSerializer): + + class Meta: + model = DossierScore + fields = ('representative', 'dossier', 'score') + + class RecommendationSerializer(serializers.HyperlinkedModelSerializer): class Meta: -- GitLab