Skip to content

Commit

Permalink
Add whipreport/annotation admin and basic display
Browse files Browse the repository at this point in the history
  • Loading branch information
ajparsons committed Dec 20, 2024
1 parent 842dd30 commit f6ac20e
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 3 deletions.
58 changes: 57 additions & 1 deletion src/votes/admin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,67 @@
# Register your models here.
from django.contrib import admin

from .models import AnalysisOverride, Update
from .models import (
Agreement,
AgreementAnnotation,
AnalysisOverride,
Division,
DivisionAnnotation,
Person,
Update,
VoteAnnotation,
WhipReport,
)

admin.site.register(Update)


@admin.register(Division)
class DivisionAdmin(admin.ModelAdmin):
list_display = ("id", "key")
search_fields = ("key",)


@admin.register(Agreement)
class AgreementAdmin(admin.ModelAdmin):
list_display = ("id", "key")
search_fields = ("key",)


@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
list_display = ("id", "name")
search_fields = ("id",)


@admin.register(AnalysisOverride)
class DivisionOverrideAdmin(admin.ModelAdmin):
list_display = ("id", "decision_key", "banned_motion_ids", "parl_dynamics_group")


@admin.register(WhipReport)
class WhipReportAdmin(admin.ModelAdmin):
list_display = ("id", "division", "party", "whip_direction", "whip_priority")
search_fields = ("division",)
autocomplete_fields = ("division",)


@admin.register(DivisionAnnotation)
class DivisionAnnotationAdmin(admin.ModelAdmin):
list_display = ("id", "division", "detail", "link")
search_fields = ("division",)
autocomplete_fields = ("division",)


@admin.register(AgreementAnnotation)
class AgreementAnnotationAdmin(admin.ModelAdmin):
list_display = ("id", "agreement", "detail", "link")
search_fields = ("agreement",)
autocomplete_fields = ("agreement",)


@admin.register(VoteAnnotation)
class VoteAnnotationAdmin(admin.ModelAdmin):
list_display = ("id", "division", "person", "detail", "link")
search_fields = ("division",)
autocomplete_fields = ("division", "person")
7 changes: 7 additions & 0 deletions src/votes/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ class WhipPriority(StrEnum):
)


class EvidenceType(StrEnum):
REP = "from_rep"
WHIP = "from_whip"
REPORTING = "from_reporting"
OTHER = "from_other"


class WhipDirection(StrEnum):
"""
This is the direction of the whip.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Generated by Django 4.2.15 on 2024-12-20 15:39

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('votes', '0010_userpersonlink'),
]

operations = [
migrations.AddField(
model_name='whipreport',
name='evidence_detai',
field=models.TextField(blank=True, default=''),
),
migrations.AddField(
model_name='whipreport',
name='evidence_type',
field=models.CharField(choices=[('from_rep', 'From Rep'), ('from_whip', 'From Whip'), ('from_reporting', 'From Reporting'), ('from_other', 'From Other')], default='from_other', max_length=255),
preserve_default=False,
),
migrations.AddField(
model_name='whipreport',
name='party',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.DO_NOTHING, related_name='whip_reports', to='votes.organization'),
preserve_default=False,
),
migrations.AlterField(
model_name='divisionannotation',
name='link',
field=models.CharField(default='', max_length=255),
),
migrations.CreateModel(
name='AgreementAnnotation',
fields=[
('id', models.BigAutoField(default=None, primary_key=True, serialize=False)),
('detail', models.CharField(default='', max_length=255)),
('link', models.CharField(default='', max_length=255)),
('agreement', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='agreement_annotations', to='votes.agreement')),
],
options={
'abstract': False,
},
),
]
71 changes: 69 additions & 2 deletions src/votes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

from .consts import (
ChamberSlug,
EvidenceType,
MotionType,
OrganisationType,
PolicyDirection,
Expand Down Expand Up @@ -637,6 +638,9 @@ class Division(DjangoVoteModel):
is_gov_breakdowns: DummyOneToMany[DivisionsIsGovBreakdown] = related_name(
"division"
)
whip_reports: DummyOneToMany[WhipReport] = related_name("division")
division_annotations: DummyOneToMany[DivisionAnnotation] = related_name("division")
vote_annotations: DummyOneToMany[VoteAnnotation] = related_name("division")
tags: DummyManyToMany[DivisionTag] = related_name("division")
motion_id: Dummy[Optional[int]] = None
motion: Optional[Motion] = field(
Expand All @@ -648,6 +652,23 @@ class Division(DjangoVoteModel):
related_name="divisions",
)

def whip_report_df(self) -> pd.DataFrame | None:
wf = list(
self.whip_reports.all().values(
"party__name", "whip_direction", "whip_priority"
)
)
if not wf:
return None
df = pd.DataFrame(data=wf)
df.columns = ["Party", "Whip direction", "Whip priority"]
# remove duplicates
df = df.drop_duplicates()
return df

def get_annotations(self) -> list[DivisionAnnotation]:
return list(self.division_annotations.all())

def analysis_override(self) -> Optional[AnalysisOverride]:
existing = getattr(self, "_override", None)
if existing:
Expand Down Expand Up @@ -840,6 +861,9 @@ def votes_df(self) -> pd.DataFrame:
)
person_to_membership_map = {x.person_id: x for x in relevant_memberships}

vote_annotations = self.vote_annotations.all()
vote_annotation_map = {x.person_id: x.url_column() for x in vote_annotations}

data = [
{
"Person": UrlColumn(url=v.person.url(), text=v.person.name),
Expand All @@ -851,6 +875,7 @@ def votes_df(self) -> pd.DataFrame:
if v.diff_from_party_average is not None
else nan
),
"Annotation": vote_annotation_map.get(v.person_id, "-"),
}
for v in self.votes.all()
]
Expand All @@ -861,6 +886,9 @@ def votes_df(self) -> pd.DataFrame:

df = pd.DataFrame(data=data)

if len(vote_annotation_map) == 0:
df = df.drop(columns=["Annotation"])

setattr(self, "_votes_df", df)

return df
Expand Down Expand Up @@ -975,6 +1003,12 @@ class Agreement(DjangoVoteModel):
related_name="agreements",
default=None,
)
agreement_annotations: DummyOneToMany[AgreementAnnotation] = related_name(
"agreement"
)

def get_annotations(self) -> list[AgreementAnnotation]:
return list(self.agreement_annotations.all())

def analysis_override(self) -> Optional[AnalysisOverride]:
existing = getattr(self, "_override", None)
Expand Down Expand Up @@ -1246,17 +1280,40 @@ def composite_key(self) -> str:
class WhipReport(DjangoVoteModel):
division_id: Dummy[int] = 0
division: DoNothingForeignKey[Division] = related_name("whip_reports")
party = DoNothingForeignKey[Organization]
party_id: Dummy[int] = 0
party: DoNothingForeignKey[Organization] = related_name("whip_reports")
whip_direction: WhipDirection
whip_priority: WhipPriority
evidence_type: EvidenceType
evidence_detai: TextField = field(default="", blank=True)


class DivisionAnnotation(DjangoVoteModel):
division_id: Dummy[int] = 0
division: DoNothingForeignKey[Division] = related_name("division_annotations")
detail: str = ""
link: str
link: str = ""

def html(self) -> str:
if self.detail and self.link:
return f"<a href='{self.link}'>{self.detail}</a>"
if self.link:
return f"<a href='{self.link}'>{self.link}</a>"
return self.detail


class AgreementAnnotation(DjangoVoteModel):
agreement_id: Dummy[int] = 0
agreement: DoNothingForeignKey[Agreement] = related_name("agreement_annotations")
detail: str = ""
link: str = ""

def html(self) -> str:
if self.detail and self.link:
return f"<a href='{self.link}'>{self.detail}</a>"
if self.link:
return f"<a href='{self.link}'>{self.link}</a>"
return self.detail


class VoteAnnotation(DjangoVoteModel):
Expand All @@ -1267,6 +1324,16 @@ class VoteAnnotation(DjangoVoteModel):
detail: str = ""
link: str

def html(self) -> str:
if self.detail and self.link:
return f"<a href='{self.link}'>{self.detail}</a>"
if self.link:
return f"<a href='{self.link}'>{self.link}</a>"
return self.detail

def url_column(self) -> UrlColumn:
return UrlColumn(url=self.link, text=self.detail)


class AnalysisOverride(DjangoVoteModel):
"""
Expand Down
16 changes: 16 additions & 0 deletions src/votes/templates/votes/decision.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,22 @@ <h2>Motion</h2>
<a href="{{ decision.motion_speech_url }}">Motion in TheyWorkForYou</a>
</p>
{% endif %}
{% with decision.get_annotations as annotations %}
{% if annotations %}
<h2>Annotations</h2>
<ul>
{% for annotation in annotations %}<li>{{ annotation.html|safe }}</li>{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% if decision.decision_type == "Division" %}
{% with decision.whip_report_df as whip_report_df %}
{% if whip_report_df is not None %}
<h2>Whip reports</h2>
{% style_df whip_report_df %}
{% endif %}
{% endwith %}
{% endif %}
{% if relevant_policies %}
<h2>Policies</h2>
<p>This decision is part of the following policies:</p>
Expand Down

0 comments on commit f6ac20e

Please sign in to comment.