Django Admin: Resizing Form Fields (for TabularInline)

Recently, one “small”* project in particular required the resizing of fields for displaying Inline Models in the admin.

For example, one inline model, “ElectroporationConditionsRecord” needed to display 11 fields.


(click image to see it full sized)

Squeezing the 11 fields into a readable row meant updating the “size” attribute of each input box.  A “default sized” input box in the admin does not include the “size” attribute, as in ‘size=”7″‘ below:

<input type=”text” size=”7” value=”0″ name=”id_days_of_drug_selection” id=”id_days_of_drug_selection”>

One way to add the “size” attribute, or any other attribute, is by making a form and connecting it to the admin.  For this example, three files are involved in making this happen:

my_appp/models.py      # definition of model ElectroporationConditionsRecord
       /forms.py
       /admin.py

(1) models.py

Here is a snippet of the ElectroporationConditionsRecord model, from the models.py file:

class ElectroporationConditions(models.Model):

    example_target_model = models.ForeignKey(ExampleTargetModel)  # example FK
    construct_name = models.CharField(max_length=40)
    drug_selection = models.CharField(max_length=40)
    days_of_drug_selection= models.IntegerField(default=0)
(etc..)

(2) forms.py

The inline model for the ElectroporationConditionsRecord in the screenshot above uses the following form, located in the forms.py file:

from django import forms

class ElectroporationConditionsForm(forms.ModelForm):
    '''ElectroporationConditionsForm.  Used to size the text input boxes'''

    class Meta:
        widgets = { 'construct_name': forms.TextInput(attrs={'size': 20})
                    , 'drug_selection': forms.TextInput(attrs={'size': 20})
                    , 'days_of_drug_selection': forms.TextInput(attrs={'size': 7})
                    , 'drug_concentration': forms.TextInput(attrs={'size': 7}) 

                    , 'dna_quantity': forms.TextInput(attrs={'size': 7})
                    , 'dna_concentration': forms.TextInput(attrs={'size': 7})
                    , 'linearized_by': forms.TextInput(attrs={'size': 7}) 

                    , 'passage': forms.TextInput(attrs={'size': 7})
                    , 'peak_voltage': forms.TextInput(attrs={'size': 7})
                    , 'time_constant': forms.TextInput(attrs={'size': 7})
                 }
# examples of other form widgets: PasswordInput, HiddenInput, Select, DateInput, etc.

Note, each key in the widgets dictionary above (e.g. ‘construct_name‘, drug_selection‘, etc.) is the name of a field in the model ElectroporationConditionsRecord.

You could also substitute the “size” attribute for a css class, as in:

              , 'time_constant': forms.TextInput(attrs={'class': 'input_sm_number'})

where the css might be something like:

             input.input_sm_number { width:6opx; }

(3) admin.py

To connect the new ElectroporationConditionsForm to the model ElectroporationConditionsRecord, a change is made in the admin.py:

# For this TabularInline Admin model, use the form that sets the size attributes
#
class ElectroporationConditionsAdminInline(admin.TabularInline):
    model = ElectroporationConditionsRecord   # from models.py
    form = ElectroporationConditionsForm      # from forms.py, sets the size attributes for the input boxes
    extra=0

# example of using the TabularInline Admin model defined above
#
class ExampleTargetModel(admin.ModelAdmin):
    # note: the ElectroporationConditionsRecord has an FK to this model, ExampleTargetModel
    inlines = (  ElectroporationConditionsAdminInline,)

Basically, that’s it.

In summary, to define the field width  in the admin model:

(a) Make a form similar to the ElectroporationConditionsForm, as in step (2) above.

(b) In your admin.py file, connect the form (ElectroporationConditionsForm) to your model, similar to the ElectroporationConditionsAdminInline model shown in step (3) above.

There are also other ways to do this, as seen on StackOverflow.com.

* The project is still small/low maintenance meaning it’s just models and the Django admin. It has 39 database tables, not including the “built-in” django tables.