"formfield_overrides" vs "formfield_for_dbfield()" vs "form" vs "get_form()" to change the width of the field in Django Admin

For example, there is Person model below:

# "models.py"

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=20)
    age = models.PositiveSmallIntegerField()
    
    def __str__(self):
        return self.name

Then, if using formfield_overrides, formfield_for_dbfield(), form or get_form() as shown below:

formfield_overrides:

# "admin.py"

from django.contrib import admin
from .models import Person
from django.db import models
from django import forms

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    formfield_overrides = { # Here
        models.PositiveSmallIntegerField: {
            'widget': forms.NumberInput(attrs={'style': 'width:50ch'})
        },
    }

formfield_for_dbfield():

# "admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin): # Here
    def formfield_for_dbfield(self, db_field, request, **kwargs):
        field = super().formfield_for_dbfield(db_field, request, **kwargs)
        if db_field.name == 'age':
            field.widget.attrs['style'] = 'width: 50ch'
        return field

form:

# "admin.py"

from django.contrib import admin
from .models import Person
from django import forms

class PersonForm(forms.ModelForm):
    age = forms.CharField(
        widget=forms.NumberInput(attrs={'style':'width:50ch'})
    )

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    form = PersonForm # Here

get_form():

# "admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin): # Here
    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['age'].widget.attrs['style'] = 'width: 50ch;'
        return form

Then, I can change the width of age field on "Add" and "Change" pages as shown below:

enter image description here

enter image description here

Now, are there any differences between formfield_overrides, formfield_for_dbfield(), form and get_form() to change the width of the field in Django Admin?

Upvotes: 0

Views: 677

Answers (1)

formfield_overrides or formfield_for_dbfield() can also change the width of the field on "Change List" page in addition to "Add" and "Change" pages in Django Admin while form or get_form() cannot.

So, if making age field viewable and editable with list_display and list_editable for formfield_overrides or formfield_for_dbfield() as shown below.

formfield_overrides:

# "admin.py"

from django.contrib import admin
from .models import Person
from django.db import models
from django import forms

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age') # Here
    list_editable = ('age',) # Here

    formfield_overrides = {
        models.PositiveSmallIntegerField: {
            'widget': forms.NumberInput(attrs={'style': 'width:50ch'})
        },
    }

formfield_for_dbfield():

# "admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age') # Here
    list_editable = ('age',) # Here

    def formfield_for_dbfield(self, db_field, request, **kwargs):
        field = super().formfield_for_dbfield(db_field, request, **kwargs)
        if db_field.name == 'age':
            field.widget.attrs['style'] = 'width: 50ch'
        return field

You can change the width of age field on "Change List" page as shown below:

enter image description here

But, if making age field viewable and editable with list_display and list_editable for form or get_form() as shown below:

form:

# "admin.py"

from django.contrib import admin
from .models import Person
from django import forms

class PersonForm(forms.ModelForm):
    age = forms.CharField(
        widget=forms.NumberInput(attrs={'style':'width:50ch'})
    )

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age') # Here
    list_editable = ('age',) # Here

    form = PersonForm

get_form():

# "admin.py"

from django.contrib import admin
from .models import Person

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age') # Here
    list_editable = ('age',) # Here

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['age'].widget.attrs['style'] = 'width: 50ch;'
        return form

You cannot change the width of age field on "Change List" page as shown below:

enter image description here

Upvotes: 1

Related Questions