Models not saving while iterating over Queryset

I’m writing a migration to fix some broken links in one of the fields on my model, but the changes don’t save to the db:

from django.db import migrations
from django.db.models import Q


def fix_invalid_links(apps, schema_editor):
    Question = apps.get_model('game', 'Question')
    for question in Question.objects.filter(~Q(valid_links=[])):
        links = question.valid_links
        fixed_links = []
        for link in links:
            ext = '.' + link.rsplit('.', 1)[1]
            match ext:
                case '.j':
                    fixed_links.append(link + 'pg')
                case '.jp':
                    fixed_links.append(link + 'g')
                case '.w':
                    fixed_links.append(link + 'mv')
                case '.wm':
                    fixed_links.append(link + 'v')
                case '.m':
                    fixed_links.append(link + 'p3')
                case '.mp':
                    fixed_links.append(link + '3')
                case _:
                    fixed_links.append(link)
        if set(links) != set(fixed_links):
            print(f'links: {links}')
            print(f'fixed_links: {fixed_links}')
            question.valid_links = fixed_links
            question.save()


class Migration(migrations.Migration):

    dependencies = [
        ('game', '0008_question_valid_links'),
    ]

    operations = [
        migrations.RunPython(
            fix_invalid_links, migrations.RunPython.noop
        ),
    ]

Judging by what’s being printed the logic seems sound, it’s just not saving the changes. I also tried it as a management command but had the same problem. Why isn’t this persisting?

What’s the data type of the valid_links field in the Question model?

valid_links = ArrayField(
        models.CharField(max_length=50, blank=True),
        size=3,
        default=list
    )

And from this statement:

you’re saying that you’re seeing the expected output from:

Can you show one such example of the output you’re getting from this?

Is this the complete fix_invalid_links function, or is there other code that you are omitting here?

Example of output for one question (questions generally only have one link associated with them, occasionally more):

links: ['https://www.j-archive.com/media/1986-03-20_J_16.mp']
fixed_links: ['https://www.j-archive.com/media/1986-03-20_J_16.mp3']

And yes this is the entire function (entire migration file actually), no code has been omitted.

Your fixed link in this example is 51 characters. My guess would be that it is being truncated at 50, which would end up making it the same as the original.

Oh wow, totally forgot that I’d set a max_length, good catch!

Doesnt violating the max_length throw an exception by default though? Or am i misremembering?

Just applied your fix and confirmed it worked, thanks again!