-
-
Save magopian/7543724 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*- | |
"""Add permissions for proxy model. | |
This is needed because of the bug https://code.djangoproject.com/ticket/11154 | |
in Django (as of 1.6, it's not fixed). | |
When a permission is created for a proxy model, it actually creates if for it's | |
base model app_label (eg: for "article" instead of "about", for the About proxy | |
model). | |
What we need, however, is that the permission be created for the proxy model | |
itself, in order to have the proper entries displayed in the admin. | |
""" | |
from __future__ import unicode_literals, absolute_import, division | |
import sys | |
from django.contrib.auth.management import _get_all_permissions | |
from django.contrib.auth.models import Permission | |
from django.contrib.contenttypes.models import ContentType | |
from django.core.management.base import BaseCommand | |
from django.db.models import get_models | |
from django.utils.encoding import smart_unicode | |
class Command(BaseCommand): | |
help = "Fix permissions for proxy models." | |
def handle(self, *args, **options): | |
for model in get_models(): | |
opts = model._meta | |
ctype, created = ContentType.objects.get_or_create( | |
app_label=opts.app_label, | |
model=opts.object_name.lower(), | |
defaults={'name': smart_unicode(opts.verbose_name_raw)}) | |
for codename, name in _get_all_permissions(opts, ctype): | |
p, created = Permission.objects.get_or_create( | |
codename=codename, | |
content_type=ctype, | |
defaults={'name': name}) | |
if created: | |
sys.stdout.write('Adding permission {}\n'.format(p)) |
If anyone is interested, https://code.djangoproject.com/ticket/11154 has been fixed and will be part of the 2.2 release.
@arthurio I am on 2.2. While running migrations, I got:
auth.0011_update_proxy_permissions
Raw Python operation -> Update the content_type of prox…
I don't know where or how to make the rest of this truncated string show up, but it seems this 'fix' is manual, not automatic. Is that what was intended?
@rebkwok I remember struggling with this once a while back. So why are all the code samples posted after your post still using name? I find this confusing. Clarification welcome.
https://docs.djangoproject.com/en/dev/internals/deprecation/
...
1.10
...
Ability to specify ContentType.name when creating a content type instance will be removed.
Finally, to all and any reading this: I find the reference to "raw python" confusing. Do they mean runPython?
https://docs.djangoproject.com/en/dev/ref/migration-operations/#django.db.migrations.operations.RunPython
@MalikRumi Checkout the 2.2.1 release notes and the related ticket. The fix should be automatic now.
import sys from django.apps import apps from django.utils.encoding import smart_text from django.contrib.auth.management import _get_all_permissions from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType # proxy model missing permission workaround - modified for Django 2.0 def proxy_perm_create(**kwargs): for model in apps.get_models(): opts = model._meta print(opts.verbose_name_raw) ctype, created = ContentType.objects.get_or_create( app_label=opts.app_label, model=opts.object_name.lower()) for code_tupel in _get_all_permissions(opts): codename = code_tupel[0] name = code_tupel[1] p, created = Permission.objects.get_or_create( codename=codename, content_type=ctype, defaults={'name': name}) if created: sys.stdout.write('Adding permission {}\n'.format(p)) models.signals.post_migrate.connect(proxy_perm_create)
How to Use @wbworks
Does anyone have a nice solution for moving from 1.11 to 2.2 if we have done this? When my migrations were run on deployment the first time I got IntegrityError (1062, "Duplicate entry...
because of django/contrib/auth/migrations/0011_update_proxy_permissions.py
We didn't need those permissions anymore so I just deleted them and re ran the migration then it worked fine, but what if someone had complex groups/permissions set up...?
@mdaizovi See my comment above, this has been fixed in thee 2.2.1 release.
The permissions are created for proxy models, just with the wrong
content_type
. I updated the code and tested in Django 1.11: