Repository: wagtail/wagtail

Issue:
Adding new pages fails with "Data too long for column 'translation_key' at row 1"
Wagtail 6.0.1
Django 5.0.3
MariaDB 10.11

Adding a new page in wagtail  fails with 
```
DataError at /iadmin/pages/add/xxx/
(1406, "Data too long for column 'translation_key' at row 1")
```
The cause is that `UUIDFields` like `translation_key` need a patch for MariaDB >= 10.7, as described 
in the Django 5 release notes  https://docs.djangoproject.com/en/5.0/releases/5.0/#migrating-existing-uuidfield-on-mariadb-10-7

Please provide migrations for this. 



Discussion:
Confirmed on current Wagtail. Starting from a fresh virtualenv and running mariadb server:

* `pip install django<5 wagtail mysqlclient`
* `wagtail start wagtailmaria`
* edit wagtailmaria/settings/base.py:
  ```
  DATABASES = {
      "default": {
          "ENGINE": "django.db.backends.mysql",
          "NAME": "wagtailmaria",
          "USERNAME": "...",
          "PASSWORD": "...",
      }
  ```
* `./manage.py migrate` ; `./manage.py createsuperuser` ; `./manage.py runserver`
* log in; editing and creating pages works fine
* `pip install -U django`
* now creating a new homepage at the top level fails on save with `django.db.utils.DataError: (1406, "Data too long for column 'translation_key' at row 1")`, and editing the existing homepage fails with `django.db.utils.DataError: (1406, "Data too long for column 'uuid' at row 1")`
This is going to be a tricky one to resolve across all environments. I can add the migration as directed by the Django docs (https://github.com/gasman/wagtail/commit/68c111652b08591b038841948d42ab71975b8178) and that does fix a project that was created under Django 4.2 and broken in an upgrade to Django 5.0 - however, a new project created under Django 5.0 (and using MariaDB's native UUIDField with no issues) now fails when running that migration with `Data too long for column 'translation_key' at row 1`. I see it's also [failing on non-MariaDB databases](https://github.com/gasman/wagtail/actions/runs/8885474283/job/24396906910), presumably because those are implementing UUIDField as a CharField _with_ the hyphen separator, which means they don't fit into a `char(32)`. I suspect the Django developers didn't consider reusable cross-platform apps like Wagtail when they rolled that change out (and wrote the release note for it) :-(

To make matters worse, it's not just Wagtail's own apps that will need migrations - one of the UUIDFields in question is in `TranslatableMixin`, so changing that at Wagtail's end will trigger a migration in any app that defines a translatable snippet model, including on non-MariaDB-based projects.

I think the answer might be to side-step the migration mechanism entirely, and provide a management command that developers can run at the point that they upgrade to Django 5.0 (or MariaDB 10.7, whichever one happens later), which finds all the affected CharField-based UUIDFields and runs an ALTER TABLE to convert them to native UUIDFields. (In other words: "rewrite this database to behave as if its migrations were run under Django 5.0/MariaDB 10.7".)
just a note:
- I applied the patch suggested in the Django5 release notes to the 3 instances of `UUIDfield` in the 3 files `wagtail/models/{i18n.py, audit_log.py, reference_index.py}`  and this works for me (without any db migration). Of course, this is not an universal solution.
- The update of MariaDB which triggered the problem happened when I updated a Debian/stable server from Debian 11 to Debian 12. 

Resolving patch:
diff --git a/wagtail/management/commands/convert_mariadb_uuids.py b/wagtail/management/commands/convert_mariadb_uuids.py
new file mode 100644
--- /dev/null
+++ b/wagtail/management/commands/convert_mariadb_uuids.py
@@ -0,0 +1,43 @@
+from django.apps import apps
+from django.core.management.base import BaseCommand
+from django.db import connection, models
+
+from wagtail.models import (
+    BaseLogEntry,
+    BootstrapTranslatableMixin,
+    ReferenceIndex,
+    TranslatableMixin,
+)
+
+
+class Command(BaseCommand):
+    help = "Converts UUID columns from char type to the native UUID type used in MariaDB 10.7+ and Django 5.0+."
+
+    def convert_field(self, model, field_name, null=False):
+        if model._meta.get_field(field_name).model != model:
+            # Field is inherited from a parent model
+            return
+
+        if not model._meta.managed:
+            # The migration framework skips unmanaged models, so we should too
+            return
+
+        old_field = models.CharField(null=null, max_length=36)
+        old_field.set_attributes_from_name(field_name)
+
+        new_field = models.UUIDField(null=null)
+        new_field.set_attributes_from_name(field_name)
+
+        with connection.schema_editor() as schema_editor:
+            schema_editor.alter_field(model, old_field, new_field)
+
+    def handle(self, **options):
+        self.convert_field(ReferenceIndex, "content_path_hash")
+
+        for model in apps.get_models():
+            if issubclass(model, BaseLogEntry):
+                self.convert_field(model, "uuid", null=True)
+            elif issubclass(model, BootstrapTranslatableMixin):
+                self.convert_field(model, "translation_key", null=True)
+            elif issubclass(model, TranslatableMixin):
+                self.convert_field(model, "translation_key")


Test patch: