2010-01-19 16 views

Respuesta

2

Creo que esto no es posible con un simple interruptor en el InlineAdmin subclase. Pero no puedo pensar en un pequeño "hack" que consigue el mismo:

utilizar el atributo template en su InlineAdmin para especificar una plantilla personalizada para hacer sus inline. Ahora copie la plantilla original que desea usar en su plantilla personalizada (por ejemplo, copie django/contrib/admin/templates/admin/edit_inline/tabular.html). Mire la fuente y busque la línea con {% for inline_admin_form in inline_admin_formset %} e inserte {% if not inline_admin_form.original %} después. También inserte {% endif %} justo antes de la etiqueta de cierre {% endfor %} .

Este método realmente solo oculta la salida de las líneas. Por lo que su todavía posible modificarlos haciendo pasar datos POST primas a la página, por ejemplo, con curl (pero el "atacante" [léase: usuario admin ;-)] debe conocer Django y cómo se genera los nombres de campos en formsets) .

El tabular.html podría parecer ahora así:

{% 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> 
+2

Creo que habría formas más limpias de hacer esto en el código Python, por lo que una subclase BaseInlineFormset que nunca muestra datos existentes y reemplaza el método apropiado en su subclase admin.ModelInline para que use su clase de formset. –

+0

Sí, estoy de acuerdo. No he pensado en eso. Tal vez tenga menos experiencia con formularios. El enfoque de la subclase es, por supuesto, mucho más limpio y no tanto un "truco". –

1
from django.forms.models import inlineformset_factory 

y luego

class ModelNameInlineFormSet(BaseInlineFormSet): 
    def __init__(self, **kwargs): 
     super(ModelNameInlineFormSet, self).__init__(**kwargs) 
     self.queryset = ModelName.objects.none() 

class ModelNameInline(admin.TabularInline): 
    formset = inlineformset_factory(ParentModelName, ModelName, 
            formset=ModelNameInlineFormSet) 
Cuestiones relacionadas