tags:

views:

129

answers:

1

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

+2  A: 

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>
Gregor Müllegger
I think there would be cleaner ways to do this in Python code, by making a BaseInlineFormset subclass that never displays existing data and overriding the proper method on your admin.ModelInline subclass to make it use your formset class.
Carl Meyer
Yes, I agree. I haven't thought about that. Maybe I have to less experience with formsets. The subclass approach is ofcourse much cleaner and not so much a "hack".
Gregor Müllegger