django-dbsettings icon indicating copy to clipboard operation
django-dbsettings copied to clipboard

Invalid ContentType after running "migrate" command

Open last-partizan opened this issue 10 years ago • 9 comments

When using django 1.7 migrations i get the following message:

> ./manage migrate
...
The following content types are stale and need to be deleted:
    core |

core - is my app where i use django-dbsettings.

I found this closed ticket in django bugtracker: https://code.djangoproject.com/ticket/23519 Here is code which creates content-type with empty model: https://github.com/zlorf/django-dbsettings/blob/master/dbsettings/management.py#L13

    ct, created = ContentType.objects.get_or_create(model='', app_label=appname,
                                                    defaults={'name': appname})

To fix this we need to tell django "we need this model, so don't touch this" or find another way to implement app-level permissions.

last-partizan avatar Nov 19 '14 12:11 last-partizan

Thanks for the info and a bug-report link. Indeed some action need to be taken. Let me think a while.

zlorf avatar Nov 19 '14 14:11 zlorf

Does this http://stackoverflow.com/a/13952198/2987806 solution suit?

wWolfovich avatar Jan 21 '15 12:01 wWolfovich

@zlorf any update on this issue? I'm gonna need to migrate to something else

vahidm avatar Oct 13 '15 08:10 vahidm

@vahidm it's safe to just ignore that warnings

last-partizan avatar Oct 13 '15 08:10 last-partizan

@vahidm No update so far, but this message (warning) is only annoying, not harmful.

zlorf avatar Oct 13 '15 08:10 zlorf

I know +1s aren't exactly helpful, but for what it's worth… I'd love a fix for this. I took a look myself and noped out of there pretty quickly; it doesn't seem like an obvious change would solve it.

MatthewWilkes avatar Apr 06 '16 21:04 MatthewWilkes

I also run into this since a while. It took my attention when I run 'migrate.py migrate' in my Jenkins deployment script. Unfortunately the deployment stuck at this point. A workaround is to use 'migrate.py migrate --no-input'. But this solution only skips that warning and don't solve the issue.

The general issue ist that permissions from django.auth are bound to models. But in dbsettings you want to bind the permission to an app. The only model you may bind the permission to is the dbsetting.models.Settings. So maybe you could change the dbsettings.management.mk_permissions:

    ct, created = ContentType.objects.get_or_create(model='', app_label=appname,
                                                    defaults={'name': appname})

to

    ct, created = ContentType.objects.get_or_create(model='settings', 
                                                    app_label='dbsettings')

(I don't know what 'name' is good for. I remember some changes in Django that this field was removed)

and

if are_global_settings:
        permission = (
            'can_edit__settings',
            'Can edit %s non-model settings' % app_label,
        )

to

if are_global_settings:
        permission = (
            'can_edit_%s_settings' % app_label,
            'Can edit %s non-model settings' % app_label,
        )

After a look at my database I found a lot of can_edit__settings with different description strings:

 959 | Can edit myapp1 non-model settings               |             199 | can_edit__settings
 974 | Can edit myapp2 non-model settings                    |             214 | can_edit__settings
 975 | Can edit myapp3 non-model settings                      |             215 | can_edit__settings
 976 | Can edit myapp4 non-model settings                       |             216 | can_edit__settings
 977 | Can edit myapp5 non-model settings                 |             217 | can_edit__settings
 978 | Can edit myapp6 non-model settings                   |             218 | can_edit__settings
 979 | Can edit myapp7 non-model settings                       |             219 | can_edit__settings
 980 | Can edit myapp8 non-model settings               |             220 | can_edit__settings

Is this a bug? Should the name of the permission be like in my proposal above? I can't see how this could work.

The disadvantage of this approach is, that you may have some 'stale' permissions. Some thoughts about this:

1.) Ignore this issue. Django does the same on removed permissions in the code. :) 2.) Write a management command for cleanup 3.) This permissions must not be deleted automatically. When you run your project in a different configuration without one of the apps that uses dbsettings, this would delete permissions that my required by another instance of your project. 4.) Remove app specific settings. Currently I can't see that the app specific settings for permissions are working at all.

If you want I can have a look at the implementation and create a PR. Unfortunately this change may break a lot of application that use the permissions.

Any thoughts?

soerenbe avatar Jun 05 '16 17:06 soerenbe

No bug here, can_edit__settings is a permission name indicating that it control app-level settings permission (model == '', hence can_edit__settings instead of can_edit_MODEL_settings for model-level settings permission).

I need to rethink the permissions here, and I like the idea of binding app-level permissions to Settings model instead of non-existing model of an app.

zlorf avatar Jun 05 '16 18:06 zlorf

Ok. That's good. So I missed something.

I think the Settings model is the only suitable model. I was thinking about models from django (e.g. django.auth.models.Permission). But this somehow hurts my feelings. :-)

soerenbe avatar Jun 05 '16 18:06 soerenbe