datamade / chi-councilmatic

:eyes: keep tabs on Chicago city council
https://chicago.councilmatic.org/
MIT License
21 stars 16 forks source link

further minimizing django councilmatic #396

Open fgregg opened 9 months ago

fgregg commented 9 months ago

it’s been productive to move the views and templates and such out of django councilmatic.

another good step would be to move all possible methods from the django councilmatic models to the chi-councilmatic proxy models

fgregg commented 8 months ago

this is not actually a good approach since we have some things set up in django_councilmatic to follow relations and get the right things back.

i think i'd like to experiment with a different approach where we extend opencivicdata models to include a slug, and then we basically replicate the model definitions from opencivicdata into chi-councilmatic, but use managed=False.

this will require us to keep these model definitions in sync, but the opencivicdata models are very slow moving.

fgregg commented 8 months ago

i wonder if an approach like this could work.

  1. do not have opencividata be an installed app
  2. in models.py for chicago, do something like
import opencividata.core

class Person(opencivicdata.core.models.Person):
    class Meta:
        managed = False
        db_table = "opencivicdata_person"

to cut down on the amount of duplication.

fgregg commented 8 months ago

i think that will work if we monkeypatch the opencivicdata.core.models as abstract.

fgregg commented 8 months ago

this is working beautifully:

from contextlib import contextmanager

@contextmanager
def abstract(base_model):

    previous_abstract_state = base_model._meta.abstract
    base_model._meta.abstract = True
    try:
        yield base_model
    finally:
        base_model._meta.abstract = previous_abstract_state

with abstract(opencivicdata.core.models.Person) as AbstractPerson:
    class TestPerson(AbstractPerson):
        class Meta:
            managed = False
            db_table = "opencivicdata_person"

        hello = 'there'
>>> from chicago.models import TestPerson
>>> TestPerson.objects.first()
<TestPerson: Martin, Matthew J.>
>>> TestPerson.objects.first().id
'ocd-person/02abf3c1-c846-4249-b086-54f1707f5a16'
>>> TestPerson.objects.first().family_name
'Martin'
>>> TestPerson.objects.first().hello
'there'