# Generated by Django 5.2.7 on 2025-11-11 14:13 import re from django.contrib.postgres.aggregates import ArrayAgg from django.db import migrations from django.db.models import Min def set_cc(apps, schema_editor): License = apps.get_model("epdb", "License") # For all existing licenses extract cc_string from link for license in License.objects.all(): pattern = r"/licenses/([^/]+)/4\.0" match = re.search(pattern, license.link) if match: license.cc_string = match.group(1) license.save() else: raise ValueError(f"Could not find license for {license.link}") # Ensure we have all licenses cc_strings = ["by", "by-nc", "by-nc-nd", "by-nc-sa", "by-nd", "by-sa"] for cc_string in cc_strings: if not License.objects.filter(cc_string=cc_string).exists(): new_license = License() new_license.cc_string = cc_string new_license.link = f"https://creativecommons.org/licenses/{cc_string}/4.0/" new_license.image_link = f"https://licensebuttons.net/l/{cc_string}/4.0/88x31.png" new_license.save() # As we might have existing Licenses representing the same License, # get min pk and all pks as a list license_lookup_qs = License.objects.values("cc_string").annotate( lowest_pk=Min("id"), all_pks=ArrayAgg("id", order_by=("id",)) ) license_lookup = { row["cc_string"]: (row["lowest_pk"], row["all_pks"]) for row in license_lookup_qs } Packages = apps.get_model("epdb", "Package") for k, v in license_lookup.items(): # Set min pk to all packages pointing to any of the duplicates Packages.objects.filter(pk__in=v[1]).update(license_id=v[0]) # remove the min pk from "other" pks as we use them for deletion v[1].remove(v[0]) # Delete redundant License objects License.objects.filter(pk__in=v[1]).delete() class Migration(migrations.Migration): dependencies = [ ("epdb", "0010_license_cc_string"), ] operations = [migrations.RunPython(set_cc)]