Readonly for existing items only in Django admin inline

Having the same problem, I came across this fix:

Create two inline objects, one with no change permission, and the other with all the fields read-only. Include both in the model admin.

class SubscriptionInline(admin.TabularInline):
    model = Subscription
    extra = 0
    readonly_fields = ['subscription', 'usedPtsStr', 'isActive', 'activationDate', 'purchaseDate']

    def has_add_permission(self, request):
        return False

class AddSupscriptionInline(admin.TabularInline):
    model = Subscription
    extra = 0
    fields = ['subscription', 'usedPoints', 'isActive', 'activationDate', 'purchaseDate']

    def has_change_permission(self, request, obj=None):
        return False

    # For Django Version > 2.1 there is a "view permission" that needs to be disabled too (https://docs.djangoproject.com/en/2.2/releases/2.1/#what-s-new-in-django-2-1)
    def has_view_permission(self, request, obj=None):
        return False

Include them in the same model admin:

class UserAdmin(admin.ModelAdmin):
    inlines = [ AddSupscriptionInline, SubscriptionInline]

To add a new subscription I use the AddSubscriptionInline in the admin. Once it is saved, the new subscription disappears from that inline, but now does appear in the SubscriptionInline, as read only.

For SubscriptionInline, it is important to mention extra = 0, so it won’t show junk read-only subscriptions.
It is better also to hide the add option for SubscriptionInline, to allow adding only via AddSubscriptionInline, by setting the has_add_permission to always return False.

Not perfect at all, but it’s the best option for me, since I must provide the ability to add subscriptions on the user admin page, but after one is added, it should be changed only via the internal app logic.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)