Fixing the auth_permission table after renaming a model in Django
Asked Answered
D

5

9

Every now and then, you have the need to rename a model in Django (or, in one recent case I encountered, split one model into two, with new/different names). (Yes, proper planning helps to avoid this situation).

After renaming corresponding tables in the db and fixing affected code, one problem remains: Any permissions granted to Users or Groups to operate on those models still references the old model names. Is there any automated or semi-automated way to fix this, or is it just a matter of manual db surgery? (in development you can drop the auth_permissions table and syncdb to recreate it, but production isn't so simple).

Disintegrate answered 27/2, 2009 at 7:12 Comment(3)
9 years later ... do you remember how you ended up doing this?Brooch
Hah, no I don't remember, sorry. Are other answers on this page helpful? Please post if you come up with a recipe that works for Django 2.Disintegrate
in my particular case, my django database was populated with an ETL script from a legacy database. I felt like fixing permissions would be followed up with fixing indices and postgresql sequences, etc., and I didn't want to go into the rabbit hole. I ended up clearing the database, re-running a django migrate with the new model names for a fresh database, and re-running the ETL scriptBrooch
A
2

Here's a snippet that fills in missing contenttypes and permissions. I wonder if it could be extended to at least do some of the donkey work for cleaning up auth_permissions.

Antipyrine answered 27/2, 2009 at 15:15 Comment(1)
Note this version of the script does not work with Django 1.0 - use djangosnippets.org/snippets/696 instead.Disintegrate
R
2

If you happened to have used a South schema migration to rename the table, the following line in the forward migration would have done this automatically:

db.send_create_signal('appname', ['modelname'])
Ric answered 11/9, 2012 at 0:6 Comment(0)
E
0

I got about half-way through a long answer that detailed the plan of attack I would take in this situation, but as I was writing I realized there probably isn't any way around having to do a maintenance downtime in this situation.

You can minimize the downtime by having a prepared loaddata script of course, although care needs to be taken to make sure the auth_perms primary keys are in sync.

Also see short answer: no automated way to do this of which I'm aware.

Enriquetaenriquez answered 27/2, 2009 at 8:13 Comment(0)
G
0

I recently had this issue and wrote a function to solve it. You'll typically have a discrepancy with both the ContentType and Permission tables if you rename a model/table. Django has built-in helper functions to resolve the issue and you can use them as follow:

from django.contrib.auth.management import create_permissions
from django.contrib.contenttypes.management import update_all_contenttypes
from django.db.models import get_apps

def update_all_content_types_and_permissions():
    for app in get_apps():
        create_permissions(app, None, 2)
    update_all_contenttypes()
Galactometer answered 11/12, 2014 at 22:16 Comment(1)
does not work in my case (Django 1.7): 'module' object has no attribute 'models_module'Expansion
O
0

I changed verbose names in my application, and in Django 2.2.7 this is the only way I found to fix permissions:

from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import Permission

class Command(BaseCommand):
    help = 'Fixes permissions names'

    def handle(self, *args, **options):
        for p in Permission.objects.filter(content_type__app_label="your_app_label_here"):
            p.name = "Can %s %s"%(p.codename.split('_')[0], p.content_type.model_class()._meta.verbose_name)
            p.save()
Orfield answered 5/1, 2020 at 17:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.