#29386: Meta Inheritance for default_permissions
-------------------------------+--------------------------------------
Reporter: Clayton Daley | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 1.11
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by Clayton Daley:
Old description:
> I add Read/Browse permissions to my models that I enforce in my views.
> For some reason, `default_permissions` isn't inheriting in the way I
> would expect. Nor does the Meta Inheritance section of the documentation
> say anything to suggest this should not be valid.
>
> Given something like:
>
> {{{
> class BreadMetaMixin(object):
> # ACTION_EDIT aliases "change" for BREAD semantics, see
> http://paul-m-jones.com/archives/291
> default_permissions = (ACTION_BROWSE, ACTION_READ, ACTION_EDIT,
> ACTION_ADD, ACTION_DELETE)
>
> class Encounter(AbstractParentModel):
> class Meta(BreadMetaMixin, AbstractParentModel.Meta):
> pass
>
> class Admission(Encounter):
> class Meta(Encounter.Meta):
> # also reproduced with non-proxy model
> proxy = True
> }}}
>
> When I `makemigrations`, Encounter detects the new permissions...
>
> {{{
> ...
> operations = [
> migrations.CreateModel(
> name='Encounter',
> ...
> options={
> 'default_permissions': ('browse', 'read', 'change',
> 'add', 'delete'),
> 'abstract': False,
> },
> ...
> }}}
>
> but Admissions does not:
>
> {{{
> ...
> operations = [
> migrations.CreateModel(
> name='Admission',
> ...
> options={
> 'abstract': False,
> 'proxy': True, # also verified with non-proxy model
> 'indexes': [],
> },
> ...
> }}}
>
> It's possible that this hasn't come up because it's masked by #11154. I
> noticed it because I'm working around #11154 using a migration like:
>
> {{{
> def add_proxy_permissions(apps, schema_editor):
> """Workaround https://code.djangoproject.com/ticket/11154 by manually
> creating the required permissions."""
> ContentType = apps.get_model('contenttypes', 'ContentType')
> Permission = apps.get_model('auth', 'Permission')
> for model in ['Admission']:
> class_ = apps.get_model('task_manager', model)
> content_type = ContentType.objects.get_for_model(class_,
> for_concrete_model=False)
> for perm in class_._meta.default_permissions:
> Permission.objects.get_or_create(
> content_type=content_type,
> codename='{}_{}'.format(perm, model.lower()),
> )
> }}}
>
> This works great on two meta models where `BreadMetaMixin` is included
> directly (e.g. `UserProxy` wraps `auth.models.User` and includes
> `BreadMetaMixin`). When I moved the code over to `Admission`, however,
> it wasn't working correctly. If I mixin `BreadMetaMixin` directly, it
> works fine so I've narrowed it down to a Meta Inheritance issue.
New description:
I add Read/Browse permissions to my models that I enforce in my views.
For some reason, `default_permissions` isn't inheriting in the way I would
expect. Nor does the Meta Inheritance section of the documentation say
anything to suggest this should not be valid.
Given something like:
{{{
class BreadMetaMixin(object):
# ACTION_EDIT aliases "change" for BREAD semantics, see
http://paul-m-jones.com/archives/291
default_permissions = (ACTION_BROWSE, ACTION_READ, ACTION_EDIT,
ACTION_ADD, ACTION_DELETE)
class Encounter(AbstractParentModel):
class Meta(BreadMetaMixin, AbstractParentModel.Meta):
pass
class Admission(Encounter):
class Meta(Encounter.Meta):
# also reproduced with non-proxy model
proxy = True
}}}
When I `makemigrations`, Encounter detects the new permissions...
{{{
...
operations = [
migrations.CreateModel(
name='Encounter',
...
options={
'default_permissions': ('browse', 'read', 'change', 'add',
'delete'),
'abstract': False,
},
...
}}}
but Admissions does not:
{{{
...
operations = [
migrations.CreateModel(
name='Admission',
...
options={
'abstract': False,
'proxy': True, # also verified with non-proxy model
'indexes': [],
},
...
}}}
It's possible that this hasn't come up because it's masked by #11154, but
it affects non-proxy models as well. I noticed it because I'm working
around #11154 using a migration like:
{{{
def add_proxy_permissions(apps, schema_editor):
"""Workaround https://code.djangoproject.com/ticket/11154 by manually
creating the required permissions."""
ContentType = apps.get_model('contenttypes', 'ContentType')
Permission = apps.get_model('auth', 'Permission')
for model in ['Admission']:
class_ = apps.get_model('task_manager', model)
content_type = ContentType.objects.get_for_model(class_,
for_concrete_model=False)
for perm in class_._meta.default_permissions:
Permission.objects.get_or_create(
content_type=content_type,
codename='{}_{}'.format(perm, model.lower()),
)
}}}
This works great on two meta models where `BreadMetaMixin` is included
directly (e.g. `UserProxy` wraps `auth.models.User` and includes
`BreadMetaMixin`). When I moved the code over to `Admission`, however, it
wasn't working correctly. If I mixin `BreadMetaMixin` directly, it works
fine so I've narrowed it down to a Meta Inheritance issue.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/29386#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/070.727f7da578d27118e5e272874f304a08%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.