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.

Published by

rprasad

Notes while working in a large academic organization.

6 thoughts on “Django Admin: Resizing Form Fields (for TabularInline)”

  1. This is probably the best explanation of django admin form customisation out there. Its simple, logical, and very easy to understand! Thank you very much good sir!

  2. Hi. Please consider changing your site styles so the code samples are readable/prinatable. They currenly appear in small boxes that require scrolling back and forth. Thanks!

  3. example to modify size of ChoiceField
    forms.py
    class FormEmpresa(ModelForm):

    name = forms.ChoiceField(label=’Name’,choices = [[0, ‘———-‘]]+[(i.id,i.nane for i in People.objects.all()])

    #just replace
    name.widget.attrs[‘style’] = ‘width:630px;’

  4. I also had to shrink a column in the admintabularinline.
    I had defined in forms.css a class
    .vIntegerTabularField {
    width: 2em; /*Nenad novo dodao da mi stane u tabular inline*/
    }
    then in the __init__ of the forms.ModelForm I have put
    self.fields[“x_pos”].widget.attrs.update({‘class’:’vIntegerTabularField’})

    hth to someone
    Nenad

Comments are closed.