Opened 2 years ago

Closed 19 months ago

#20376 closed Bug (needsinfo)

Inline permissions on self-related m2m field

Reported by: ppetrid Owned by: nobody
Component: contrib.admin Version: 1.5
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


I have a model that relates to itself like this:

class Article(models.Model):
  related_articles = models.ManyToManyField('self', blank=True, null=True)

For presentation purposes I choose to display it as inline on the admin website:

class RelatedArticlesInline(admin.TabularInline):
  model = Article.related_articles.through
  fk_name = 'from_article'
  raw_id_fields = ('to_article',)

class ArticleAdmin(admin.ModelAdmin):
  inlines = (RelatedArticlesInline,), ArticleAdmin)

The problem: Non-superuser staff accounts are not able to see the related articles inline, despite they have been assigned all Article permissions.

The reason: Obviously this is a permission bug in the inline. It appears the problem is lying in django.contrib.admin.options.InlineModelAdmin.has_change_permission(). In line 1556 (as of current master source) we do:

for field in opts.fields:
  if field.rel and != self.parent_model:
    opts =

Since both ForeignKey fields of the intermediate model point to the parent model (self-relation), the code fails to discover the appropriate permissions.

This is checked with Django 1.5.

Change History (3)

comment:1 Changed 2 years ago by DrMeers

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

This seems to be a rather unusual setup, using the 'through' model and the auto-created foreign keys in the inline definition. The code will fall back to checking permissions on "change_article_related_articles". Are the 'from_' and 'to_' foreign keys documented anywhere? If not, this could be beyond the scope of core support, and perhaps best handled by defining your own has_change_permission.

The InlineModelAdmin.has_change_permission definition could detect the self-relation and fall back to the permissions for the model. If so, I think it would be nice to make self-referential auto-created m2m models more easily identifiable as part of the patch; it seems at the moment we have iterate through the foreign keys and compare them.

comment:2 Changed 2 years ago by ppetrid

I solved my original problem by overriding the has_change_permission() method. To the best of my knowledge these auto-generated fields are not documented, but it felt natural to use the through model in the inline and set the 'fk_name' property for my use case. In my point of view this is still a bug since the loop assumes there is at least one ForeignKey not related to the parent model. Then we rely on the fact we know normally this won't be a problem, but it's still an assumption and this use case brought it up. Finally, I second your thoughts on the self-referential auto-generated m2m models. This iteration should be totally avoided in the first place somehow.

comment:3 Changed 19 months ago by timo

  • Resolution set to needsinfo
  • Status changed from new to closed

@ppetrid - I'm going to close this as "needs info" since it doesn't seem to be entirely clear what the next step would be for another person to pick this up (accepted tickets that will never be worked on aren't of much use). If you'd like to provide a patch, please do so and reopen this ticket. Thanks!

Note: See TracTickets for help on using tickets.
Back to Top