From 400568dd368e9865e115cc4a51eda010da0230b7 Mon Sep 17 00:00:00 2001 From: Mario Sergio Date: Mon, 30 Sep 2024 15:50:03 -0300 Subject: [PATCH 1/2] feat(vote): Converted places logic to database query --- app/contrib/bonde/models.py | 24 +++++++++++ .../candidature/locations_utils.py | 40 ++++--------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/app/contrib/bonde/models.py b/app/contrib/bonde/models.py index 65cd14a5..c2c46114 100644 --- a/app/contrib/bonde/models.py +++ b/app/contrib/bonde/models.py @@ -357,3 +357,27 @@ class Meta: @property def render_success(self): return "forms/success.html" + + +class PlacesIBGE(models.Model): + uf = models.CharField(max_length=2) + nome_uf = models.CharField(max_length=100) + regiao_geografica_intermediaria = models.CharField(max_length=10) + nome_regiao_geografica_intermediaria = models.CharField(max_length=100) + regiao_geografica_imediata = models.CharField(max_length=10) + nome_regiao_geografica_imediata = models.CharField(max_length=100) + mesorregiao_geografica = models.CharField(max_length=10) + nome_mesorregiao = models.CharField(max_length=100) + microrregiao_geografica = models.CharField(max_length=10) + nome_microrregiao = models.CharField(max_length=100) + municipio = models.CharField(max_length=10) + codigo_municipio_completo = models.CharField(max_length=10) + nome_municipio = models.CharField(max_length=100) + distrito = models.CharField(max_length=10) + codigo_distrito_completo = models.CharField(max_length=15) + nome_distrito = models.CharField(max_length=100) + sigla_uf = models.CharField(max_length=2) + + class Meta: + managed = False + db_table = 'places_ibge' diff --git a/app/org_eleicoes/votepeloclima/candidature/locations_utils.py b/app/org_eleicoes/votepeloclima/candidature/locations_utils.py index 0c604958..6fb4538d 100644 --- a/app/org_eleicoes/votepeloclima/candidature/locations_utils.py +++ b/app/org_eleicoes/votepeloclima/candidature/locations_utils.py @@ -1,37 +1,13 @@ -from django.conf import settings -from pathlib import Path -import csv -from typing import List, Tuple, Set +from typing import List, Tuple +from contrib.bonde.models import PlacesIBGE -csv_filename = Path(settings.BASE_DIR) / "org_eleicoes/votepeloclima/candidature/csv/places.csv" - -def read_csv_file(file_path: Path) -> List[dict]: - with open(file_path) as f: - reader = csv.DictReader(f) - reader.fieldnames = [field.strip() for field in reader.fieldnames] - return [row for row in reader] - -def get_states(column_label="Nome_UF") -> List[Tuple[str, str]]: - rows = read_csv_file(csv_filename) - states = set() - for row in rows: - uf = row["UF"].strip() - state_name = row[column_label].strip() - states.add((uf, state_name)) - return sorted(list(states), key=lambda x: x[1]) +def get_states(column_label="nome_uf") -> List[Tuple[str, str]]: + states = PlacesIBGE.objects.values('uf', column_label).distinct() + return sorted([(state['uf'], state[column_label]) for state in states], key=lambda x: x[1]) def get_ufs() -> List[Tuple[str, str]]: - return get_states(column_label="Nome_UF") + return get_states(column_label="nome_uf") def get_choices(uf: str) -> List[Tuple[str, str]]: - rows = read_csv_file(csv_filename) - choices = [] - seen_cities = set() - for row in rows: - if row["UF"].strip() == uf: - city_code = row["Código Município Completo"].strip() - city_name = row["Nome_Município"].strip() - if city_name not in seen_cities: - choices.append((city_code, city_name)) - seen_cities.add(city_name) - return sorted(choices, key=lambda x: x[1]) + choices = PlacesIBGE.objects.filter(uf=uf).values('codigo_municipio_completo', 'nome_municipio').distinct() + return sorted([(choice['codigo_municipio_completo'], choice['nome_municipio']) for choice in choices], key=lambda x: x[1]) From de1e5c3c086f4be2724b311665940e47a069a3b3 Mon Sep 17 00:00:00 2001 From: Mario Sergio Date: Tue, 1 Oct 2024 11:51:58 -0300 Subject: [PATCH 2/2] feat(vote): display ufs on public pages --- app/org_eleicoes/votepeloclima/candidature/forms/filters.py | 4 ++-- app/org_eleicoes/votepeloclima/candidature/forms/register.py | 4 ++-- app/org_eleicoes/votepeloclima/candidature/locations_utils.py | 2 +- app/org_eleicoes/votepeloclima/candidature/models.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/org_eleicoes/votepeloclima/candidature/forms/filters.py b/app/org_eleicoes/votepeloclima/candidature/forms/filters.py index 4d1fec4d..9c9b9ad1 100644 --- a/app/org_eleicoes/votepeloclima/candidature/forms/filters.py +++ b/app/org_eleicoes/votepeloclima/candidature/forms/filters.py @@ -8,7 +8,7 @@ from ..layout import NoCrispyField from ..choices import Gender, Color, Sexuality from ..fields import CepField, ButtonCheckboxSelectMultiple, ButtonRadioSelect -from ..locations_utils import get_ufs, get_choices +from ..locations_utils import get_states, get_choices from ..models import Candidature from .register import ProposeForm @@ -36,7 +36,7 @@ class FilterFormHeader(RemoveRequiredMixin, forms.ModelForm): field="state", label="Estado", placeholder="Todos os estados", - choices=[("", "Todos os estados")] + lazy(get_ufs, list)(), + choices=[("", "Todos os estados")] + lazy(get_states, list)(), ) city = CepField( field="city", parent="state", label="Município", placeholder="Selecione" diff --git a/app/org_eleicoes/votepeloclima/candidature/forms/register.py b/app/org_eleicoes/votepeloclima/candidature/forms/register.py index 9fd35adb..3e62f85c 100644 --- a/app/org_eleicoes/votepeloclima/candidature/forms/register.py +++ b/app/org_eleicoes/votepeloclima/candidature/forms/register.py @@ -9,7 +9,7 @@ from crispy_forms.layout import Layout, Div, Field, HTML from bootstrap_datepicker_plus.widgets import DatePickerInput -from ..locations_utils import get_ufs, get_choices +from ..locations_utils import get_states, get_choices from ..choices import ( PoliticalParty, IntendedPosition, @@ -192,7 +192,7 @@ class ApplicationForm(EntangledModelFormMixin, DisabledMixin, forms.ModelForm): field="state", label="Estado", placeholder="Selecione", - choices=[("", "Selecione")] + lazy(get_ufs, list)(), + choices=[("", "Selecione")] + lazy(get_states, list)(), help_text="Estado onde você está concorrendo", ) city = CepField( diff --git a/app/org_eleicoes/votepeloclima/candidature/locations_utils.py b/app/org_eleicoes/votepeloclima/candidature/locations_utils.py index 6fb4538d..b3a8345e 100644 --- a/app/org_eleicoes/votepeloclima/candidature/locations_utils.py +++ b/app/org_eleicoes/votepeloclima/candidature/locations_utils.py @@ -6,7 +6,7 @@ def get_states(column_label="nome_uf") -> List[Tuple[str, str]]: return sorted([(state['uf'], state[column_label]) for state in states], key=lambda x: x[1]) def get_ufs() -> List[Tuple[str, str]]: - return get_states(column_label="nome_uf") + return get_states(column_label="sigla_uf") def get_choices(uf: str) -> List[Tuple[str, str]]: choices = PlacesIBGE.objects.filter(uf=uf).values('codigo_municipio_completo', 'nome_municipio').distinct() diff --git a/app/org_eleicoes/votepeloclima/candidature/models.py b/app/org_eleicoes/votepeloclima/candidature/models.py index 6c60ae93..e4c931e2 100644 --- a/app/org_eleicoes/votepeloclima/candidature/models.py +++ b/app/org_eleicoes/votepeloclima/candidature/models.py @@ -5,7 +5,7 @@ from django.utils.html import mark_safe from .choices import CandidatureFlowStatus, IntendedPosition, PoliticalParty, Gender, Color, Sexuality, Education -from .locations_utils import get_choices, get_states +from .locations_utils import get_choices, get_ufs # Acompanhar validação da candidatura @@ -58,7 +58,7 @@ def status(self): @property def get_state_display(self): - states = dict(get_states()) + states = dict(get_ufs()) return states.get(self.state, "") @property