Colin
Colin

Reputation: 3752

django admin not showing abstract base class fields

I have

class BaseModelMixin(models.Model):
    class Meta:
        abstract = True
    uuid = models.UUIDField(default=uuid4, editable=False, db_index=True)
    created_on = models.DateTimeField(default=now, editable=False, blank=True)
    updated_on = models.DateTimeField(default=now, editable=False, blank=True)

and

class Something(BaseModelMixin):
    whatever = models.TextField(blank=True, null=True)

class SomethingElse(BaseModelMixin):
    whoever = models.TextField(blank=True, null=True)

on the admin site, for each Something, I see whatever, but not uuid, created_on, or updated_on. I must be missing something obvious... it'd be surprising if the django admin didn't automatically show me these fields.

I definitely want the abstract; I don't want an additional table, I want the uuid, created_on, updated_on fields to be in the concrete class tables, and they are. They just don't show up in the django admin site.

What am I doing wrong?


Anoop's answers is partially correct:

class BaseModelMixinAdmin(admin.ModelAdmin):
    readonly_fields=('uuid','created_on','updated_on')

but then also:

admin.site.register(Something, BaseModelMixinAdmin)
admin.site.register(SomethingElse, BaseModelMixinAdmin)

... which is a little irritating that I have to do this at all, but oh well, it ain't that bad...

Upvotes: 1

Views: 1925

Answers (2)

claypooj
claypooj

Reputation: 413

@Anoop's answer is correct, but to make it more clear, if you're using an abstract model like the BaseModelMixin used by @Colin (the OP), your admin.py file could look like this:

# admin.py
# ===================================================================
from django.contrib import admin
from .models import *

# Use this as a mixin to store common logic.
class BaseModelMixinAdmin(admin.ModelAdmin):
    readonly_fields = (
        'uuid',
        'created_on',
        'updated_on',
    )

# Inherit the mixin.
class SomethingAdmin(BaseModelMixinAdmin, admin.ModelAdmin):
    pass

# Inherit the mixin.
class SomethingElseAdmin(BaseModelMixinAdmin, admin.ModelAdmin):
    pass

admin.site.register(Something, SomethingAdmin)
admin.site.register(SomethingElse, SomethingElseAdmin)

This way, you can still individually modify each admin model and the common logic is inherited from the BaseModelMixinAdmin.

Tested using Python 3.8.10 and Django 4.0.

Upvotes: 1

Anoop
Anoop

Reputation: 1435

If you just want to see the non editable fields in admin panel. Use read only fields in model admin

class BaseModelMixinAdmin(admin.ModelAdmin):
    readonly_fields=('uuid',)

Upvotes: 3

Related Questions