Migration 0002_alter_testmodel_options fails with ForeignKeyViolation when permissions are assigned to users/groups #640
-
DescriptionMigration The ErrorFull traceback: Root CauseIn def remove_test_model_default_permissions(apps, schema_editor):
ContentType = apps.get_model("contenttypes", "ContentType")
Permission = apps.get_model("auth", "Permission")
db_alias = schema_editor.connection.alias
try:
test_model_content_type = ContentType.objects.using(db_alias).get(app_label="db", model="testmodel")
Permission.objects.using(db_alias).filter(content_type=test_model_content_type).delete()
except ContentType.DoesNotExist:
returnThis deletes How to Reproduce
Suggested FixClear the M2M references before deleting the permissions: def remove_test_model_default_permissions(apps, schema_editor):
ContentType = apps.get_model("contenttypes", "ContentType")
Permission = apps.get_model("auth", "Permission")
db_alias = schema_editor.connection.alias
try:
test_model_content_type = ContentType.objects.using(db_alias).get(
app_label="db", model="testmodel"
)
except ContentType.DoesNotExist:
return
permissions = Permission.objects.using(db_alias).filter(
content_type=test_model_content_type
)
# Clear M2M references before deleting permissions
UserPermission = apps.get_model("auth", "User_user_permissions") # or use raw SQL
GroupPermission = apps.get_model("auth", "Group_permissions")
# Alternatively, using raw SQL to be safe across custom user models:
permission_ids = list(permissions.values_list("id", flat=True))
if permission_ids:
schema_editor.execute(
"DELETE FROM auth_user_user_permissions WHERE permission_id IN %s",
[tuple(permission_ids)],
)
schema_editor.execute(
"DELETE FROM auth_group_permissions WHERE permission_id IN %s",
[tuple(permission_ids)],
)
permissions.delete()WorkaroundManually clear the references before running the migration: DELETE FROM auth_user_user_permissions
WHERE permission_id IN (
SELECT p.id FROM auth_permission p
JOIN django_content_type ct ON p.content_type_id = ct.id
WHERE ct.app_label = 'db' AND ct.model = 'testmodel'
);
DELETE FROM auth_group_permissions
WHERE permission_id IN (
SELECT p.id FROM auth_permission p
JOIN django_content_type ct ON p.content_type_id = ct.id
WHERE ct.app_label = 'db' AND ct.model = 'testmodel'
);Then re-run Environment
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Hi @kumarnmanoj 👋, Thank you for reaching out. Please consider upgrading to version 4, which doesn't require migrations anymore. Since you added the users to a group, I don't think this applies to many users. Considering that you found a workaround for your project, I would refrain from a backport to v3. I must also urge you to upgrade to Django 5.2. Django 4.2 will end extended security support for Django 4.2 LTS in a month. Cheers! |
Beta Was this translation helpful? Give feedback.
Hi @kumarnmanoj 👋,
Thank you for reaching out. Please consider upgrading to version 4, which doesn't require migrations anymore.
Since you added the users to a group, I don't think this applies to many users. Considering that you found a workaround for your project, I would refrain from a backport to v3.
I must also urge you to upgrade to Django 5.2. Django 4.2 will end extended security support for Django 4.2 LTS in a month.
Cheers!
Joe