Ticket #8060: admin_inline_permissions_v1.diff

File admin_inline_permissions_v1.diff, 6.7 KB (added by Stephan Jaensch, 13 years ago)
  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index 5271e02..f2cf662 100644
    a b class ModelAdmin(BaseModelAdmin):  
    306306        self.model = model
    307307        self.opts = model._meta
    308308        self.admin_site = admin_site
    309         self.inline_instances = []
    310         for inline_class in self.inlines:
    311             inline_instance = inline_class(self.model, self.admin_site)
    312             self.inline_instances.append(inline_instance)
    313309        if 'action_checkbox' not in self.list_display and self.actions is not None:
    314310            self.list_display = ['action_checkbox'] +  list(self.list_display)
    315311        if not self.list_display_links:
    class ModelAdmin(BaseModelAdmin):  
    319315                    break
    320316        super(ModelAdmin, self).__init__()
    321317
     318    def get_inline_instances(self, user=None, action=None):
     319        inline_instances = []
     320        for inline_class in self.inlines:
     321            inline = inline_class(self.model, self.admin_site)
     322            if user:
     323                if inline.opts.auto_created:
     324                    # The model was auto-created as intermediary for a
     325                    # ManyToMany-relationship, find out the destination model
     326                    for field in inline.opts.fields:
     327                        if isinstance(field, models.ForeignKey) and field.rel.to != inline.opts.auto_created:
     328                            perm_opts = field.rel.to._meta
     329                else:
     330                    perm_opts = inline.opts
     331                perm_string = perm_opts.app_label + '.'
     332                if action == 'change':
     333                    # Currently, we can't make sure the user can only edit
     334                    # existing inlines or only add new ones but not edit
     335                    # existing ones. So we only allow editing if the user
     336                    # has both permissions.
     337                    if not user.has_perm(perm_string + perm_opts.get_change_permission()):
     338                        continue
     339                if not user.has_perm(perm_string + perm_opts.get_add_permission()):
     340                    continue
     341                if not user.has_perm(perm_string + perm_opts.get_delete_permission()):
     342                    inline.can_delete = False
     343            inline_instances.append(inline)
     344
     345        return inline_instances
     346
     347    @property
     348    def inline_instances(self):
     349        return self.get_inline_instances()
     350
    322351    def get_urls(self):
    323352        from django.conf.urls import patterns, url
    324353
    class ModelAdmin(BaseModelAdmin):  
    499528            fields=self.list_editable, **defaults)
    500529
    501530    def get_formsets(self, request, obj=None):
    502         for inline in self.inline_instances:
     531        action = ('change' if obj else 'add')
     532        for inline in self.get_inline_instances(request.user, action):
    503533            yield inline.get_formset(request, obj)
    504534
    505535    def get_paginator(self, request, queryset, per_page, orphans=0, allow_empty_first_page=True):
    class ModelAdmin(BaseModelAdmin):  
    898928
    899929        ModelForm = self.get_form(request)
    900930        formsets = []
     931        inline_instances = self.get_inline_instances(request.user, 'add')
    901932        if request.method == 'POST':
    902933            form = ModelForm(request.POST, request.FILES)
    903934            if form.is_valid():
    class ModelAdmin(BaseModelAdmin):  
    907938                form_validated = False
    908939                new_object = self.model()
    909940            prefixes = {}
    910             for FormSet, inline in zip(self.get_formsets(request), self.inline_instances):
     941            for FormSet, inline in zip(self.get_formsets(request), inline_instances):
    911942                prefix = FormSet.get_default_prefix()
    912943                prefixes[prefix] = prefixes.get(prefix, 0) + 1
    913944                if prefixes[prefix] != 1:
    class ModelAdmin(BaseModelAdmin):  
    935966                    initial[k] = initial[k].split(",")
    936967            form = ModelForm(initial=initial)
    937968            prefixes = {}
    938             for FormSet, inline in zip(self.get_formsets(request),
    939                                        self.inline_instances):
     969            for FormSet, inline in zip(self.get_formsets(request), inline_instances):
    940970                prefix = FormSet.get_default_prefix()
    941971                prefixes[prefix] = prefixes.get(prefix, 0) + 1
    942972                if prefixes[prefix] != 1:
    class ModelAdmin(BaseModelAdmin):  
    952982        media = self.media + adminForm.media
    953983
    954984        inline_admin_formsets = []
    955         for inline, formset in zip(self.inline_instances, formsets):
     985        for inline, formset in zip(inline_instances, formsets):
    956986            fieldsets = list(inline.get_fieldsets(request))
    957987            readonly = list(inline.get_readonly_fields(request))
    958988            prepopulated = dict(inline.get_prepopulated_fields(request))
    class ModelAdmin(BaseModelAdmin):  
    9941024
    9951025        ModelForm = self.get_form(request, obj)
    9961026        formsets = []
     1027        inline_instances = self.get_inline_instances(request.user, 'change')
    9971028        if request.method == 'POST':
    9981029            form = ModelForm(request.POST, request.FILES, instance=obj)
    9991030            if form.is_valid():
    class ModelAdmin(BaseModelAdmin):  
    10031034                form_validated = False
    10041035                new_object = obj
    10051036            prefixes = {}
    1006             for FormSet, inline in zip(self.get_formsets(request, new_object),
    1007                                        self.inline_instances):
     1037            for FormSet, inline in zip(self.get_formsets(request, new_object), inline_instances):
    10081038                prefix = FormSet.get_default_prefix()
    10091039                prefixes[prefix] = prefixes.get(prefix, 0) + 1
    10101040                if prefixes[prefix] != 1:
    class ModelAdmin(BaseModelAdmin):  
    10251055        else:
    10261056            form = ModelForm(instance=obj)
    10271057            prefixes = {}
    1028             for FormSet, inline in zip(self.get_formsets(request, obj), self.inline_instances):
     1058            for FormSet, inline in zip(self.get_formsets(request, obj), inline_instances):
    10291059                prefix = FormSet.get_default_prefix()
    10301060                prefixes[prefix] = prefixes.get(prefix, 0) + 1
    10311061                if prefixes[prefix] != 1:
    class ModelAdmin(BaseModelAdmin):  
    10411071        media = self.media + adminForm.media
    10421072
    10431073        inline_admin_formsets = []
    1044         for inline, formset in zip(self.inline_instances, formsets):
     1074        for inline, formset in zip(inline_instances, formsets):
    10451075            fieldsets = list(inline.get_fieldsets(request, obj))
    10461076            readonly = list(inline.get_readonly_fields(request, obj))
    10471077            prepopulated = dict(inline.get_prepopulated_fields(request, obj))
Back to Top