Is it possible to have an admin inline without original data being shown?

django, python

Solution

I think this is not possible with a simple switch in the `InlineAdmin` subclass. But I can think of a small "hack" that achieves the same:

Use the `template` attribute on your `InlineAdmin` to specify a custom template to render your inlines. Now copy the original template you want to use into your custom template (e.g. copy `django/contrib/admin/templates/admin/edit_inline/tabular.html`). Look at the source and find the line with `{% for inline_admin_form in inline_admin_formset %}` and insert `{% if not inline_admin_form.original %}` after it. Also insert `{% endif %}` right before the closing `{% endfor %}` tag.

This method actualy just hides the output of the inlines. So its still possible to modify them by passing raw POST data to the page, for example with `curl` (but the "attacker" [read: admin user ;-)] must know django and how it generates the fieldnames in formsets).

The `tabular.html` might look now like this:

{% load i18n %}
<div class="inline-group">
  <div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
{{ inline_admin_formset.formset.management_form }}
<fieldset class="module">
   <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
   {{ inline_admin_formset.formset.non_form_errors }}
   <table>
     <thead><tr>
     {% for field in inline_admin_formset.fields %}
       {% if not field.is_hidden %}
         <th {% if forloop.first %}colspan="2"{% endif %}>{{ field.label|capfirst }}</th>
        {% endif %}
     {% endfor %}
     {% if inline_admin_formset.formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %}
     </tr></thead>

     <tbody>
     {% for inline_admin_form in inline_admin_formset %}
     {% if not inline_admin_form.original %}
        {% if inline_admin_form.form.non_field_errors %}
        <tr><td colspan="{{ inline_admin_form.field_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
        {% endif %}
        <tr class="{% cycle row1,row2 %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}">

        <td class="original">
          {% if inline_admin_form.original or inline_admin_form.show_url %}<p>
          {% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
          {% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.id }}/">{% trans "View on site" %}</a>{% endif %}
            </p>{% endif %}
          {% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
          {{ inline_admin_form.fk_field.field }}
          {% spaceless %}
          {% for fieldset in inline_admin_form %}
            {% for line in fieldset %}
              {% for field in line %}
                {% if field.is_hidden %} {{ field.field }} {% endif %}
              {% endfor %}
            {% endfor %}
          {% endfor %}
          {% endspaceless %}
        </td>

        {% for fieldset in inline_admin_form %}
          {% for line in fieldset %}
            {% for field in line %}
              <td class="{{ field.field.name }}">
              {{ field.field.errors.as_ul }}
              {{ field.field }}
              </td>
            {% endfor %}
          {% endfor %}
        {% endfor %}

        {% if inline_admin_formset.formset.can_delete %}
          <td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td>
        {% endif %}

        </tr>

     {% endif %}
     {% endfor %}
     </tbody>
   </table>

</fieldset>
  </div>

  {# <ul class="tools"> #}
  {#   <li><a class="add" href="">Add another {{ inline_admin_formset.opts.verbose_name|title }}</a></li> #}
  {# </ul> #}

</div>

Problem

In the django admin I have a model with an inline. I would like to be able to only show "add new" lines for the inline, and not show any preexisting, original data in the table belonging to the inline. Is this possible? I have tried every combination of `max_num` and `extra`, and it always shows existing table data. Thanks

Original source