How to add readonly inline on django admin
Asked Answered
R

4

65

I am using django 1.4 and I have a many2many field, so when creating the admin site I wanted to add this field as an inline, here is some code:

class SummaryInline(admin.TabularInline):
    model = ParserError.summaries.through


class MyClassAdmin(admin.ModelAdmin):
    list_display = ('classifier', 'name', 'err_count', 'supported')
    fields = ('classifier', 'name', 'err_count', 'err_classifier', 'supported')
    inlines = (SummaryInline,)
    readonly_fields = ('classifier', 'err_count')

So my question is, how can I make the inline field readonly?

Rataplan answered 14/6, 2013 at 22:43 Comment(0)
R
83

After a while of trying to find the name I figured out thanks to this answer, so I checked the names at self.opts.local_fields and found the name of the middle table and added it to readonly_fields, setting can_delete to False.

class SummaryInline(admin.TabularInline):
    model = ParserError.summaries.through
    readonly_fields = ('myclasssummary',)
    can_delete = False

pretty simple but took me a while so I figured out it was a good idea to add it here.

Rataplan answered 14/6, 2013 at 22:43 Comment(4)
I'm not sure you can/should use can_delete = False. You can use def has_delete_permission(self, request, obj=None): return False instead. See docs: docs.djangoproject.com/en/2.1/ref/contrib/adminDialecticism
what is myclasssummary in the readonly_fields? is it table name or field name from summaries model?Quamash
@tamarabyte answer worked for me, not this one. Maybe change the accepted answer ?Hemia
@RustamGuliev I can't see anything in the documentation that says can_delete shouldn't be used.Cicely
D
50

Additionally, if you do not want the ability to add/delete the rows, you can add these definitions.

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

def has_delete_permission(self, request, obj=None):
    return False
Devotion answered 8/6, 2015 at 8:41 Comment(1)
Add these functions below class SummaryInline(admin.TabularInline):Darill
S
41

You can make the entire inline readonly by adding:

class UnitsInline(admin.TabularInline):

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

This will prevent anyone from editing the entry from the admin.

Another example that prevents, adding, deletion and displays all the inline fields as readonly:

class ReadOnlyInline(admin.TabularInline):
    def has_change_permission(self, request, obj=None):
        return False

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

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

    def get_readonly_fields(self, request, obj=None):
        return list(super().get_fields(request, obj))
Sherrellsherrer answered 9/1, 2019 at 16:39 Comment(5)
I'm using django 1.11 and this causes no related records to show. I guess because I can't edit them?Hubbell
You'll have to add whatever fields you want to show up for the inline as readonly fields. I'll update my answer with an example.Sherrellsherrer
For me, this prevents the inline from being rendered even for folks that have those permissions.Pasahow
This worked for me, but the get_readonly_fields was not required. Also make sure you specify model.Cicely
@Hubbell I'm also using 1.11 and have the same problem. If I'm not mistaken, I believe this was fixed last year with this ticket in a much newer version of Django -- code.djangoproject.com/ticket/31867Breger
S
6

Thanks Keval Prabhu

class UnitsInline(admin.TabularInline):
    model = Units
    extra = 0
    verbose_name = 'Units'
    verbose_name_plural = 'Units of company'
    
    def has_add_permission(self, request, obj=None):
        return False
    def has_delete_permission(self, request, obj=None):
        return False
Shaggy answered 28/9, 2017 at 9:56 Comment(2)
Why is ** for has_add_permission, it throws an error for meDiatomite
he was trying to bold. Ignore the **Dimitry

© 2022 - 2024 — McMap. All rights reserved.