Skip to content

WIP: chore(deps): Upgrade to Django 5.2#177

Closed
crankynetman wants to merge 7 commits intomainfrom
topic/chriscummings/django-5-upgrade-woohoo
Closed

WIP: chore(deps): Upgrade to Django 5.2#177
crankynetman wants to merge 7 commits intomainfrom
topic/chriscummings/django-5-upgrade-woohoo

Conversation

@crankynetman
Copy link
Copy Markdown
Collaborator

@crankynetman crankynetman commented Nov 11, 2025

Well, since it's 2025, I decided to spend down a small nation's amount of energy on Vibe Coding® an upgrade to django 5.2 and python 3.13.

It made a ton of changes I don't understand, but it's less than I figured. And FWIW, the same approaches came about by gemini, claude, and GPT 5o.

I hate this, but the tests do pass locally, so I figured i'd throw this up here for discussion.

@crankynetman crankynetman changed the title chore(deps): Upgrade to Django 5.2 WIP: chore(deps): Upgrade to Django 5.2 Nov 11, 2025
@github-actions
Copy link
Copy Markdown

File Coverage
All files 80%
config/consumers.py 77%
config/urls.py 69%
config/settings/base.py 69%
config/settings/local.py 72%
scram/route_manager/admin.py 55%
scram/route_manager/authentication_backends.py 83%
scram/route_manager/models.py 70%
scram/route_manager/views.py 86%
scram/route_manager/api/serializers.py 92%
scram/route_manager/api/views.py 74%
scram/shared/shared_code.py 56%
scram/templates/403.html 91%
scram/templates/404.html 91%
scram/templates/base.html 99%
scram/templates/route_manager/home.html 80%

Minimum allowed coverage is 50%

Generated by 🐒 cobertura-action against e0b02f7

else
echo "No unapplied migrations."
fi
python manage.py migrate --fake-initial --noinput
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why were we able to simplify so much? This seems much less brittle which is great, but are we looking at any side effects? We were conditionally doing this before so was that just not required?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We likely don't need --fake-initial because we've always had migrations be part of things.

I'm still not sure why we have this step at all. Won't migrations always be unapplied on a fresh database? It seems like this was actually originally a "check for migrations that weren't comitted" step which is good, but I think could be rewritten or we could leave it the way it was originally and change the wording.

Comment thread config/consumers.py
import logging

from asgiref.sync import sync_to_async
from channels.db import database_sync_to_async
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if my understanding is correct this is basically like some additional ORM aware niceties that channels takes advantage of. this seems like a very good change.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. We should doublecheck if we can also move to just using the decorator for this, but here's the docs on this, seems like an easy win/drop-in

https://channels.readthedocs.io/en/latest/topics/databases.html#database-sync-to-async

Comment thread requirements/base.txt
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the idea and I'm not opposed to dropping versioning, but on the other hand it seems like it's generally been better for us than just taking anything. Maybe we can find a middle ground and just do major version pinning? This goes for all the requirements files.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should re-visit this as part of the uv migration (#199 ). I think that moving to ~= X.X (where the X.X is what pip has resolved to and tests pass with) for now in this PR would likely be best.

Maybe we as a short-term don't pin anything, after this merge (or maybe as part of it?) we do the #199 work and rely on the lock file for build reproducibility and then only pin things that we really need pinned? Then do dependabot (#201 ) ASAP?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice this would close (or at least go a long way towards closing) #168

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I think we probably want to give it a close look but this does seem harmless. We definitely need to merge #188 first though since there are a few changes to migrations over there.

We also need to double-check that we have got rid of index_together everywhere in the codebase.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see why this is bad, but does it suggest we don't need to use WhoFilter anymore? I think I liked testing WhoFilter directly instead of testing the same thing in a different way. I do think we want to keep it since it's what is used on the admin panel to allow you to filter the list based on the user who added the entry. Maybe I'm overthinking it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's try getting rid of this entire change because I don't think it's needed.

self.superuser = get_user_model().objects.create_superuser("admin", "admin@es.net", "admintestpassword")
self.client.login(username="admin", password="admintestpassword")

# Create the ActionType
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The block actiontype is created by default in one of the early migrations. We can depend on it existing, but maybe this is a case of "better to be explicit"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this was only needed because of the weird migration change? Worth testing with and without this change to see if it even matters.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also looking at this more, we should only use get not get_or_create as we'd want this to fail if the migrations aren't there (cuz this is there).

I think we can likely remove this entirely, it's mostly just a bit more readable maybe not really.

Comment thread scram/users/admin.py
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we want this change, but I need to better understand the usage here. password1 and password2 to me suggests a whole password management solution that I don't think we use.

else
echo "No unapplied migrations."
fi
python manage.py migrate --fake-initial --noinput
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We likely don't need --fake-initial because we've always had migrations be part of things.

I'm still not sure why we have this step at all. Won't migrations always be unapplied on a fresh database? It seems like this was actually originally a "check for migrations that weren't comitted" step which is good, but I think could be rewritten or we could leave it the way it was originally and change the wording.

Comment thread config/settings/base.py
"channels",
"corsheaders",
"crispy_forms",
"django_celery_beat",
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just cleaning up a dangling dependency

Comment thread config/consumers.py
import logging

from asgiref.sync import sync_to_async
from channels.db import database_sync_to_async
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. We should doublecheck if we can also move to just using the decorator for this, but here's the docs on this, seems like an easy win/drop-in

https://channels.readthedocs.io/en/latest/topics/databases.html#database-sync-to-async

Comment thread config/consumers.py
routes = await sync_to_async(list)(Entry.objects.filter(is_active=True).values_list("route__route", flat=True))
routes = await database_sync_to_async(list)(
Entry.objects.filter(is_active=True).values_list("route__route", flat=True)
)
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's ruff, buddy

Comment thread requirements/base.txt
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should re-visit this as part of the uv migration (#199 ). I think that moving to ~= X.X (where the X.X is what pip has resolved to and tests pass with) for now in this PR would likely be best.

Maybe we as a short-term don't pin anything, after this merge (or maybe as part of it?) we do the #199 work and rely on the lock file for build reproducibility and then only pin things that we really need pinned? Then do dependabot (#201 ) ASAP?

Comment on lines +10 to 11
from scram.route_manager.models import ActionType, Entry
from scram.route_manager.models import Client as ClientModel
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs some isort love

]

# Create the ActionType
self.actiontype, _ = ActionType.objects.get_or_create(name="block")
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing here, we should make sure we need this and if so, move to get only.

self.unauthorized_user = User.objects.create(username="unauthorized")

self.readonly_group = Group.objects.get(name="readonly")
# Create the groups that the migration would normally create and assign permissions
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, likely related to the migration change to pytest. Why do we need to change that? Seems like we want to run migrations before tests and then this should be here already.



class TestTranslatorBaseCase(TestCase):
class TestTranslatorBaseCase(TransactionTestCase):
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not needed; probably doesn't hurt.

is_admin = groups_overlap(claimed_groups, settings.SCRAM_ADMIN_GROUPS)
if groups_overlap(claimed_groups, settings.SCRAM_READWRITE_GROUPS):
effective_groups.append(Group.objects.get(name="readwrite"))
readwrite_group, created = Group.objects.get_or_create(name="readwrite")
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again get vs get_or_create

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, let's revert this whole file and then make sure that migrations are a) running appropriately or b) have the right data so we don't do this here, in prod.

@crankynetman crankynetman marked this pull request as draft May 1, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants