Initial commit
This commit is contained in:
0
app/speakers/__init__.py
Executable file
0
app/speakers/__init__.py
Executable file
3
app/speakers/admin.py
Executable file
3
app/speakers/admin.py
Executable file
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
10
app/speakers/apps.py
Executable file
10
app/speakers/apps.py
Executable file
@ -0,0 +1,10 @@
|
||||
from django.apps import AppConfig
|
||||
from watson import search as watson
|
||||
|
||||
|
||||
class SpeakersConfig(AppConfig):
|
||||
name = 'speakers'
|
||||
|
||||
def ready(self):
|
||||
Speaker = self.get_model("Speaker")
|
||||
watson.register(Speaker, exclude=["short_vita"])
|
11
app/speakers/forms.py
Executable file
11
app/speakers/forms.py
Executable file
@ -0,0 +1,11 @@
|
||||
from django import forms
|
||||
|
||||
|
||||
class SearchForm(forms.Form):
|
||||
"""
|
||||
Configures the html input form for the speaker search.
|
||||
"""
|
||||
query = forms.CharField(label="Suche MdB", max_length="200")
|
||||
|
||||
query.widget.attrs.update({"class": "autocomplete materialize-textarea",
|
||||
"id": "icon_prefix2"})
|
115
app/speakers/management/commands/import_speakers.py
Executable file
115
app/speakers/management/commands/import_speakers.py
Executable file
@ -0,0 +1,115 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from speakers.models import Speaker, LegislativeInfo, LegislativeInstitution
|
||||
import datetime
|
||||
from lxml import etree
|
||||
from tqdm import tqdm
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ("Adds speakers (MdBs) to the database using the django models"
|
||||
" syntax. Speakers will be added from the official"
|
||||
" Stammdatenbank.xml. Input is the Stammdatenbank.xml specified"
|
||||
" by a path.")
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("input_path",
|
||||
type=str)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
file_path = options["input_path"]
|
||||
# self.stdout.write("Reading data from file: " + file_path)
|
||||
tree = etree.parse(file_path)
|
||||
speakers = tree.xpath("//MDB")
|
||||
for speaker_element in tqdm(speakers, desc="Importing speaker data"):
|
||||
speaker = Speaker()
|
||||
id = speaker_element.xpath("./ID")[0]
|
||||
speaker.id = id.text
|
||||
last_name = speaker_element.xpath("./NAMEN/NAME/NACHNAME")[0]
|
||||
speaker.last_name = last_name.text
|
||||
first_name = speaker_element.xpath("./NAMEN/NAME/VORNAME")[0]
|
||||
speaker.first_name = first_name.text
|
||||
nobility = speaker_element.xpath("./NAMEN/NAME/ADEL")[0]
|
||||
speaker.nobility = nobility.text
|
||||
name_prefix = speaker_element.xpath("./NAMEN/NAME/PRAEFIX")[0]
|
||||
speaker.name_prefix = name_prefix.text
|
||||
# self.stdout.write("Reading data for speaker: "
|
||||
# + str(id.text)
|
||||
# + " "
|
||||
# + str(first_name.text)
|
||||
# + " "
|
||||
# + str(last_name.text))
|
||||
title = speaker_element.xpath("./NAMEN/NAME/ANREDE_TITEL")[0]
|
||||
speaker.title = title.text
|
||||
birthday = speaker_element.xpath("./BIOGRAFISCHE_ANGABEN/GEBURTSDATUM")[0]
|
||||
speaker.birthday = birthday.text
|
||||
birthplace = speaker_element.xpath("./BIOGRAFISCHE_ANGABEN/GEBURTSORT")[0]
|
||||
speaker.birthplace = birthplace.text
|
||||
country_of_birth = speaker_element.xpath("./BIOGRAFISCHE_ANGABEN/GEBURTSLAND")[0]
|
||||
speaker.country_of_birth = country_of_birth.text
|
||||
day_of_death = speaker_element.xpath("./BIOGRAFISCHE_ANGABEN/STERBEDATUM")[0]
|
||||
speaker.day_of_death = day_of_death.text
|
||||
occupation = speaker_element.xpath("./BIOGRAFISCHE_ANGABEN/BERUF")[0]
|
||||
speaker.occupation = occupation.text
|
||||
short_vita = speaker_element.xpath("./BIOGRAFISCHE_ANGABEN/VITA_KURZ")[0]
|
||||
speaker.short_vita = short_vita.text
|
||||
party = speaker_element.xpath("./BIOGRAFISCHE_ANGABEN/PARTEI_KURZ")[0]
|
||||
speaker.party = party.text
|
||||
speaker.save()
|
||||
|
||||
legislative_periods = speaker_element.xpath("./WAHLPERIODEN/WAHLPERIODE/WP")
|
||||
legislative_period_start_dates = speaker_element.xpath("./WAHLPERIODEN/WAHLPERIODE/MDBWP_VON")
|
||||
legislative_period_end_dates = speaker_element.xpath("./WAHLPERIODEN/WAHLPERIODE/MDBWP_BIS")
|
||||
mandate_types = speaker_element.xpath("./WAHLPERIODEN/WAHLPERIODE/MANDATSART")
|
||||
legislative_institutions = speaker_element.xpath("./WAHLPERIODEN/WAHLPERIODE/INSTITUTIONEN/INSTITUTION/INS_LANG")
|
||||
zipped_infos = zip(legislative_periods,
|
||||
legislative_period_start_dates,
|
||||
legislative_period_end_dates,
|
||||
mandate_types,
|
||||
legislative_institutions)
|
||||
for p, sd, ed, m, i in zipped_infos:
|
||||
legislative_info = LegislativeInfo()
|
||||
legislative_info.foreign_speaker = speaker
|
||||
legislative_info.legislative_period = p.text
|
||||
if(sd.text is not None):
|
||||
sd = datetime.datetime.strptime(sd.text, "%d.%m.%Y")
|
||||
sd = datetime.datetime.strftime(sd, "%Y-%m-%d")
|
||||
legislative_info.legislative_period_start_date = sd
|
||||
if(ed.text is not None):
|
||||
ed = datetime.datetime.strptime(ed.text, "%d.%m.%Y")
|
||||
ed = datetime.datetime.strftime(ed, "%Y-%m-%d")
|
||||
legislative_info.legislative_period_end_date = ed
|
||||
legislative_info.mandate_type = m.text
|
||||
# legislative_info.legislative_institution = i.text
|
||||
legislative_info.save()
|
||||
|
||||
for period in speaker_element.xpath("./WAHLPERIODEN/WAHLPERIODE"):
|
||||
# print("==============")
|
||||
legislative_institutions = period.xpath("./INSTITUTIONEN/INSTITUTION/INS_LANG")
|
||||
# print([e.text for e in legislative_institutions])
|
||||
instition_start_dates = period.xpath("./INSTITUTIONEN/INSTITUTION/MDBINS_VON")
|
||||
# print([e.text for e in instition_start_dates])
|
||||
instition_end_dates = period.xpath("./INSTITUTIONEN/INSTITUTION/MDBINS_BIS")
|
||||
# print([e.text for e in instition_end_dates])
|
||||
# print("==============")
|
||||
zipped_institutions = zip(legislative_institutions,
|
||||
instition_start_dates,
|
||||
instition_end_dates)
|
||||
for institution, start_date, end_date in zipped_institutions:
|
||||
legislative_institution = LegislativeInstitution()
|
||||
legislative_institution.foreign_speaker = speaker
|
||||
current_period = period.xpath("./WP")[0]
|
||||
legislative_institution.current_period = current_period.text
|
||||
legislative_institution.institution = institution.text
|
||||
if(start_date.text is not None):
|
||||
start_date = datetime.datetime.strptime(start_date.text,
|
||||
"%d.%m.%Y")
|
||||
start_date = datetime.datetime.strftime(start_date,
|
||||
"%Y-%m-%d")
|
||||
legislative_institution.institution_start_date = start_date
|
||||
if(end_date.text is not None):
|
||||
end_date = datetime.datetime.strptime(end_date.text,
|
||||
"%d.%m.%Y")
|
||||
end_date = datetime.datetime.strftime(end_date,
|
||||
"%Y-%m-%d")
|
||||
legislative_institution.institution_end_date = end_date
|
||||
legislative_institution.save()
|
0
app/speakers/migrations/__init__.py
Normal file
0
app/speakers/migrations/__init__.py
Normal file
74
app/speakers/models.py
Executable file
74
app/speakers/models.py
Executable file
@ -0,0 +1,74 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Speaker(models.Model):
|
||||
"""
|
||||
This models contains general data about one MdB. Data will be imported from
|
||||
the Stammdatenbank.xml via the custom django-admin command import_speakers.py.
|
||||
"""
|
||||
id = models.IntegerField(verbose_name="MdB ID", primary_key=True)
|
||||
last_name = models.CharField(verbose_name="Nachname", max_length=50)
|
||||
first_name = models.CharField(verbose_name="Vorname", max_length=50)
|
||||
nobility = models.CharField(verbose_name="Adelstitel", max_length=50,
|
||||
null=True)
|
||||
name_prefix = models.CharField(verbose_name="Namenspräfix", max_length=50,
|
||||
null=True)
|
||||
title = models.CharField(verbose_name="Akademischer Titel", null=True,
|
||||
blank=True, max_length=50)
|
||||
birthday = models.IntegerField(verbose_name="Geburtstag", )
|
||||
birthplace = models.CharField(verbose_name="Geburtsort", null=True,
|
||||
blank=True, max_length=50)
|
||||
country_of_birth = models.CharField(verbose_name="Geburtsland", null=True,
|
||||
blank=True, max_length=50)
|
||||
day_of_death = models.IntegerField(verbose_name="Todesjahr", null=True,
|
||||
blank=True)
|
||||
|
||||
occupation = models.TextField(verbose_name="Beruf")
|
||||
short_vita = models.TextField(verbose_name="Kurzbiographie", default=None,
|
||||
null=True, blank=True)
|
||||
party = models.CharField(verbose_name="Partei", null=True, blank=True,
|
||||
max_length=50)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id) + " " + self.first_name + " " + self.last_name
|
||||
|
||||
|
||||
class LegislativeInfo(models.Model):
|
||||
"""
|
||||
This model contains data about the periods an MdB was an active part of the
|
||||
Deutsche Bundestag. Needs a foreign key which is the coresponding Speaker
|
||||
entry.
|
||||
"""
|
||||
foreign_speaker = models.ForeignKey("Speaker", on_delete=models.CASCADE)
|
||||
legislative_period = models.IntegerField(verbose_name="Wahlperiode",
|
||||
null=True)
|
||||
legislative_period_start_date = models.DateField(verbose_name="MdB von",
|
||||
null=True)
|
||||
legislative_period_end_date = models.DateField(verbose_name="MdB bis",
|
||||
null=True)
|
||||
mandate_type = models.CharField(verbose_name="Mandatsart", null=True,
|
||||
blank=True, max_length=50)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.foreign_speaker) + " " + str(self.legislative_period)
|
||||
|
||||
|
||||
class LegislativeInstitution(models.Model):
|
||||
"""
|
||||
This model contains data about the instituions an MdB was part of during a
|
||||
specific legislative period. Needs a foreign key which is the coresponding
|
||||
Speaker entry.
|
||||
"""
|
||||
foreign_speaker = models.ForeignKey("Speaker",
|
||||
on_delete=models.CASCADE)
|
||||
current_period = models.IntegerField(verbose_name="Wahlperiode",
|
||||
null=True)
|
||||
institution = models.CharField(verbose_name="Institut", null=True,
|
||||
blank=True, max_length=255)
|
||||
institution_start_date = models.DateField(verbose_name="Mitglied von",
|
||||
null=True)
|
||||
institution_end_date = models.DateField(verbose_name="Mitglied bis",
|
||||
null=True)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.foreign_legislative_info) + " " + str(self.institution)
|
19
app/speakers/tables.py
Executable file
19
app/speakers/tables.py
Executable file
@ -0,0 +1,19 @@
|
||||
import django_tables2 as tables
|
||||
from .models import Speaker
|
||||
from django_tables2.utils import A # alias for Accessor
|
||||
|
||||
|
||||
class SpeakerTable(tables.Table):
|
||||
"""
|
||||
Configures the table showing all speakers. Inserts a column with links to
|
||||
the profile of one speaker. Also defines all shown columns.
|
||||
"""
|
||||
link = tables.LinkColumn("MdB", text="Profil", args=[A("id")],
|
||||
orderable=False,
|
||||
attrs={"a": {"class": "waves-effect waves-light btn light-green darken-3"}}) # Adds colum with Link to Profile
|
||||
|
||||
class Meta:
|
||||
model = Speaker
|
||||
fields = ("last_name", "first_name", "party", "id")
|
||||
template_name = "speakers/table.html"
|
||||
empty_text = ("Für den eingegebenen Suchbegriff gibt es leider keine Ergebnisse.")
|
120
app/speakers/templates/speakers/speaker.html
Executable file
120
app/speakers/templates/speakers/speaker.html
Executable file
@ -0,0 +1,120 @@
|
||||
{% extends "blog/base.html" %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12 m4 l4">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title center-align">
|
||||
{% if current_speaker.title %}
|
||||
{{current_speaker.title}}
|
||||
{% endif %}
|
||||
{% if current_speaker.nobility %}
|
||||
{{current_speaker.nobility}}
|
||||
{% endif %}
|
||||
{{current_speaker.first_name}}
|
||||
{% if current_speaker.name_prefix %}
|
||||
{{current_speaker.name_prefix}}
|
||||
{% endif %}
|
||||
{{current_speaker.last_name}}</span>
|
||||
<p class="center-align"><i class="large material-icons blue-grey-text darken-4">account_circle</i></p>
|
||||
<span class="card-title">Biographie</span>
|
||||
<ul>
|
||||
<li><i class="material-icons blue-grey-text darken-4" style="margin-right: 10px;">cake</i> Geburtstag: {{current_speaker.birthday}}</li>
|
||||
<br />
|
||||
{% if current_speaker.day_of_death %}
|
||||
<li><b style="font-size: 2em;" class="blue-grey-text darken-4">†</b><span style="position: relative; right: -20px;"> Todesjahr:
|
||||
{{ current_speaker.day_of_death}}</span></li>
|
||||
<br />
|
||||
{% endif %}
|
||||
<li><i class="material-icons blue-grey-text darken-4" style="margin-right: 10px;">home</i> Geburtsort: {{current_speaker.birthplace}}</li>
|
||||
<br />
|
||||
<li><i class="material-icons blue-grey-text darken-4" style="margin-right: 10px;">work</i> Beruf: {{current_speaker.occupation}}</li>
|
||||
<br />
|
||||
<li><i class="material-icons blue-grey-text darken-4" style="margin-right: 10px;">fingerprint</i> Bundestags ID: {{current_speaker.id}}</li>
|
||||
<br />
|
||||
<li><i class="material-icons blue-grey-text darken-4" style="margin-right: 10px;">people</i> Partei: {{current_speaker.party}}<a class="tooltipped" data-position="bottom" data-tooltip="Aktuelle eingetragene Partei, bei der die Person Mitglied ist oder war. "><i
|
||||
class="material-icons blue-grey-text darken-4">info_outline</i></a></li>
|
||||
<br />
|
||||
<li><i class="material-icons blue-grey-text darken-4" style="margin-right: 10px;">filter_9_plus</i> Reden/Redebeiträge insgesamt: {{speech_count}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="collapsible expandable hoverable">
|
||||
{% if current_speaker.short_vita %}
|
||||
<li>
|
||||
<div class="collapsible-header">Kurzbiographie</div>
|
||||
<div class="collapsible-body white"><span>{{current_speaker.short_vita}}</span></div>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% for period in sorted_l_info %}
|
||||
<li>
|
||||
<div class="collapsible-header">
|
||||
<i class="material-icons blue-grey-text darken-4" style="margin-right: 10px;">library_books</i> Wahlperiode {{period.legislative_period}}
|
||||
</div>
|
||||
<div class="collapsible-body white">
|
||||
<ul>
|
||||
<span class="card-title">Mitglied des Bundestags</span>
|
||||
<li>Mitglied von {{period.legislative_period_start_date|date:"d.m.Y"}} bis
|
||||
{% if period.legislative_period_end_date is None %}
|
||||
heute
|
||||
{% else %}
|
||||
{{period.legislative_period_end_date|date:"d.m.Y"}}
|
||||
{% endif %}
|
||||
</li>
|
||||
<br />
|
||||
<li>Mandatsart: {{period.mandate_type}}
|
||||
<li>
|
||||
<br />
|
||||
<span class="card-title">Institutions und Fraktionszugehörigkeit</span>
|
||||
{% for institution in sorted_i_info %}
|
||||
{% if institution.current_period == period.legislative_period %}
|
||||
<li><b>{{institution.institution}}</b>
|
||||
<li>
|
||||
<br />
|
||||
{% if institution.institution_start_date is not None %}
|
||||
<li>Von {{institution.institution_start_date|date:"d.m.Y"}} bis
|
||||
{% if institution.institution_end_date is None %}
|
||||
heute
|
||||
{% else %}
|
||||
{{institution.institution_end_date|date:"d.m.Y"}}
|
||||
{% endif %}
|
||||
<li>
|
||||
<br />
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col s12 m8">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Reden</span>
|
||||
<div class="card-content">
|
||||
<p>Alle Reden, die von {% if current_speaker.title %}
|
||||
{{current_speaker.title}}
|
||||
{% endif %}
|
||||
{% if current_speaker.nobility %}
|
||||
{{current_speaker.nobility}}
|
||||
{% endif %}
|
||||
{{current_speaker.first_name}}
|
||||
{% if current_speaker.name_prefix %}
|
||||
{{current_speaker.name_prefix}}
|
||||
{% endif %}
|
||||
{{current_speaker.last_name}} als MdB gehalten wurden.
|
||||
<div style="overflow-x:auto;">
|
||||
{% render_table speech_table %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
34
app/speakers/templates/speakers/speakers.html
Executable file
34
app/speakers/templates/speakers/speakers.html
Executable file
@ -0,0 +1,34 @@
|
||||
{% extends "blog/base.html" %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<span class="card-title">Mitglieder des Bundestags</span>
|
||||
<p>Dies ist eine Liste aller Abgeordneten seit 1949 bis einschließlich der aktuellen Wahlperiode. Die Liste kann sortiert und durchsucht werden.</p>
|
||||
<p>Ausgangsdaten für diese Liste können auf der <a href="https://www.bundestag.de/service/opendata">offiziellen Seite des Bundestags</a> heruntergeladen werden.</p>
|
||||
<p>Für jede Person ist ein Profil angelegt, dass Informationen zu dieser bereithält und alle Reden bzw. Redebeiträge dieser gesammelt darstellt.</p>
|
||||
<br />
|
||||
<div class="row">
|
||||
<form method="GET" class="col l4 offset-l8 m6 offset-m6 s12">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="input-field">
|
||||
<i class="material-icons prefix">search</i>
|
||||
{{form}}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div style="overflow-x:auto;">
|
||||
{% render_table table %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
95
app/speakers/templates/speakers/table.html
Executable file
95
app/speakers/templates/speakers/table.html
Executable file
@ -0,0 +1,95 @@
|
||||
{% load django_tables2 %}
|
||||
{% load i18n %}
|
||||
{% block table-wrapper %}
|
||||
{% block table %}
|
||||
<table {% render_attrs table.attrs %} class="highlight">
|
||||
{% block table.thead %}
|
||||
{% if table.show_header %}
|
||||
<thead {{ table.attrs.thead.as_html }}>
|
||||
<tr>
|
||||
{% for column in table.columns %}
|
||||
<th {{ column.attrs.th.as_html }}>
|
||||
{% if column.orderable %}
|
||||
<a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}"><i class="material-icons ">sort</i> {{ column.header }}</a>
|
||||
{% else %}
|
||||
{{ column.header }}
|
||||
{% endif %}
|
||||
</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
{% endif %}
|
||||
{% endblock table.thead %}
|
||||
{% block table.tbody %}
|
||||
<tbody {{ table.attrs.tbody.as_html }}>
|
||||
{% for row in table.paginated_rows %}
|
||||
{% block table.tbody.row %}
|
||||
<tr {{ row.attrs.as_html }}>
|
||||
{% for column, cell in row.items %}
|
||||
<td {{ column.attrs.td.as_html }}>{% if column.localize == None %}{{ cell }}{% else %}{% if column.localize %}{{ cell|localize }}{% else %}{{ cell|unlocalize }}{% endif %}{% endif %}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endblock table.tbody.row %}
|
||||
{% empty %}
|
||||
{% if table.empty_text %}
|
||||
{% block table.tbody.empty_text %}
|
||||
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
|
||||
{% endblock table.tbody.empty_text %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endblock table.tbody %}
|
||||
{% block table.tfoot %}
|
||||
{% if table.has_footer %}
|
||||
<tfoot {{ table.attrs.tfoot.as_html }}>
|
||||
<tr>
|
||||
{% for column in table.columns %}
|
||||
<td {{ column.attrs.tf.as_html }}>{{ column.footer }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
{% endif %}
|
||||
{% endblock table.tfoot %}
|
||||
</table>
|
||||
{% endblock table %}
|
||||
|
||||
{% block pagination %}
|
||||
{% if table.page and table.paginator.num_pages > 1 %}
|
||||
<ul class="pagination">
|
||||
{% if table.page.has_previous %}
|
||||
{% block pagination.previous %}
|
||||
<li class="previous waves-effect">
|
||||
<a href="{% querystring table.prefixed_page_field=table.page.previous_page_number %}">
|
||||
{% trans '<i class="material-icons">chevron_left</i>' %}
|
||||
</a>
|
||||
</li>
|
||||
{% endblock pagination.previous %}
|
||||
{% endif %}
|
||||
{% if table.page.has_previous or table.page.has_next %}
|
||||
{% block pagination.range %}
|
||||
{% for p in table.page|table_page_range:table.paginator %}
|
||||
<li {% if p == table.page.number %}class="active light-green darken-3"{% endif %} class="waves-effect">
|
||||
{% if p == '...' %}
|
||||
<a href="#">{{ p }}</a>
|
||||
{% else %}
|
||||
<a href="{% querystring table.prefixed_page_field=p %}">
|
||||
{{ p }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% endblock pagination.range %}
|
||||
{% endif %}
|
||||
{% if table.page.has_next %}
|
||||
{% block pagination.next %}
|
||||
<li class="next waves-effect">
|
||||
<a href="{% querystring table.prefixed_page_field=table.page.next_page_number %}">
|
||||
{% trans '<i class="material-icons">chevron_right</i>' %}
|
||||
</a>
|
||||
</li>
|
||||
{% endblock pagination.next %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock pagination %}
|
||||
{% endblock table-wrapper %}
|
3
app/speakers/tests.py
Executable file
3
app/speakers/tests.py
Executable file
@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
7
app/speakers/urls.py
Executable file
7
app/speakers/urls.py
Executable file
@ -0,0 +1,7 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.speakers, name="MdBs"),
|
||||
path("mdb/<int:id>", views.speaker, name="MdB"),
|
||||
]
|
52
app/speakers/views.py
Executable file
52
app/speakers/views.py
Executable file
@ -0,0 +1,52 @@
|
||||
from django.shortcuts import render
|
||||
from django_tables2 import RequestConfig
|
||||
from .models import Speaker, LegislativeInfo, LegislativeInstitution
|
||||
from speeches.models import Speech
|
||||
from .tables import SpeakerTable
|
||||
from speeches.tables import SpeakerSpeechTable
|
||||
from django.http import Http404
|
||||
from watson import search as watson
|
||||
from .forms import SearchForm
|
||||
from speeches.forms import SearchFormSpeech
|
||||
|
||||
|
||||
def speakers(request):
|
||||
if(request.method == "GET"):
|
||||
form = SearchForm(request.GET)
|
||||
if(form.is_valid()):
|
||||
query = form.cleaned_data["query"]
|
||||
search_results = watson.filter(Speaker, query)
|
||||
table = SpeakerTable(search_results)
|
||||
RequestConfig(request, paginate={'per_page': 20}).configure(table)
|
||||
context = {"title": "Suchergebnisse für " + query,
|
||||
"form": form, "table": table}
|
||||
return render(request, "speakers/speakers.html", context)
|
||||
else:
|
||||
form = SearchForm()
|
||||
table = SpeakerTable(Speaker.objects.all().order_by("last_name"))
|
||||
RequestConfig(request, paginate={'per_page': 20}).configure(table)
|
||||
context = {"title": "Suche", "table": table, "form": form}
|
||||
return render(request, "speakers/speakers.html", context)
|
||||
|
||||
|
||||
def speaker(request, id):
|
||||
try:
|
||||
current_speaker = Speaker.objects.get(pk=id)
|
||||
speech_count = len(Speech.objects.filter(foreign_speaker=id))
|
||||
current_legislative_info = LegislativeInfo.objects.filter(foreign_speaker=id)
|
||||
sorted_l_info = current_legislative_info.order_by("legislative_period")
|
||||
institution_info = LegislativeInstitution.objects.filter(foreign_speaker=id)
|
||||
sorted_i_info = institution_info.order_by("current_period")
|
||||
table = SpeakerSpeechTable(Speech.objects.filter(foreign_speaker=id))
|
||||
RequestConfig(request, paginate={'per_page': 20}).configure(table)
|
||||
except Speaker.DoesNotExist:
|
||||
raise Http404("Speaker does not exist")
|
||||
context = {"title": ("MdB – "
|
||||
+ current_speaker.first_name
|
||||
+ " " + current_speaker.last_name),
|
||||
"current_speaker": current_speaker,
|
||||
"sorted_l_info": sorted_l_info,
|
||||
"sorted_i_info": sorted_i_info,
|
||||
"speech_table": table,
|
||||
"speech_count": speech_count}
|
||||
return render(request, "speakers/speaker.html", context)
|
Reference in New Issue
Block a user