[Solved]-Django disable editing (but allow adding) in TabularInline view


User django admin build in function has_change_permission() and return false to restrict object Edit view.

class SuperviseeAdmin(admin.TabularInline):
  model = Supervisee

  def has_change_permission(self, request):
      return False

class SupervisorAdmin(admin.ModelAdmin):
  inlines = [SuperviseeAdmin]

admin.site.register(Supervisor, SupervisorAdmin)


You can try creating a separate inline class (see the InlineModelAdmin docs) that uses a custom ModelForm where you can customise the the clean method to throw an error when trying to update:

from django.contrib import admin
from django.core.exceptions import ValidationError
from django.forms import ModelForm

from myapp.models import Supervisee

class SuperviseeModelForm(ModelForm):
    class Meta(object):
        model = Supervisee
        # other options ...

    def clean(self):
        if self.instance.pk:
            # instance already exists
            raise ValidationError('Update not allowed')
        # instance doesn't exist yet, continue
        return super(SuperviseeModelForm, self).clean()

class SuperviseeInline(admin.TabularInline):
    model = Supervisee
    form = SuperviseeModelForm

class SuperviseeAdmin(admin.ModelAdmin):
    inlines = [SuperviseeInline]


See this solution: Django admin: make field editable in add but not edit

Override get_readonly_fields method:

def get_readonly_fields(self, request, obj=None):
    if obj: # obj is not None, so this is an edit
        return ['name1',..] # Return a list or tuple of readonly fields' names
    else: # This is an addition
        return []


just make all your fields readonly_fields in your admin.TabularInline as :

class SuperviseeAdmin(admin.TabularInline):
  model = Supervisee

  readonly_fields = ('your_field', 'your_field2',)


class SuperviseeAdmin(admin.TabularInline):
  model = Supervisee

  def __init__(self, *args, **kwargs):
        super(SuperviseeAdmin, self).__init__(*args, **kwargs)
        self.list_display_links = (None, )

Leave a comment