Tuesday, 19 January 2021

Django admin: inherit base class field such that it is used to set the model's field on save

Say I have models A, B, C, each have a foreign key field foo to model Foo. foo is a difficult field to select, hence we rather use a field bar (a foreign key to model Bar), and depending on the entry selected, our code selects the correct Foo. The bar field is not part of A, B, or C, only foo is.

Now in django admin models for A, B, and C, I am trying to make a common base model they can inherit from which will handle this functionality.

# --- models.py

class BaseModel(models.Model):
    foo = models.ForeignKey(Foo, on_delete=models.PROTECT)

class A(BaseModel):
    name = models.CharField("A name", max_length=200, unique=True)

class B(BaseModel):
    enabled = models.BooleanField("Be enabled", default=True, )

class C(BaseModel):
    count = SmallFloatField("Count of things", )

# --- admin.py

class BaseAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)  # This form object does not have .fields attribute
        form.fields = [x for x in form.fields if x != 'foo']
        form.fields += 'bar'
        return form

@admin.register(A)
class AAdmin(BaseAdmin):
    pass

@admin.register(B)
class BAdmin(BaseAdmin):
    pass

@admin.register(C)
class CAdmin(BaseAdmin):
    pass

Unfortunately form.fields does not exist on the form object. How does one replace a field of a base ModelAdmin class such that its derived classes inherit these changes too?

Note: Using Django 3



from Django admin: inherit base class field such that it is used to set the model's field on save

No comments:

Post a Comment