可以在不显示原始数据的情况下有内联管理员吗?
在Django的管理后台,我有一个模型里面有一个内联(inline)。我希望只显示“添加新项”的选项,而不显示内联表格中已经存在的原始数据。这样做可以吗?我试过各种组合的max_num
和extra
,但总是会显示已有的表格数据。
谢谢
2 个回答
1
from django.forms.models import inlineformset_factory
然后
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)
2
我觉得在InlineAdmin
的子类中简单地切换是不可能的。不过,我想到一个小“技巧”可以实现类似的效果:
你可以在InlineAdmin
中使用template
属性,指定一个自定义的模板来渲染你的内联内容。接下来,把你想用的原始模板复制到你的自定义模板中(比如复制django/contrib/admin/templates/admin/edit_inline/tabular.html
)。然后查看源代码,找到包含{% for inline_admin_form in inline_admin_formset %}
的那一行,并在它后面插入{% if not inline_admin_form.original %}
。同时,在关闭的{% endfor %}
标签前插入{% endif %}
。
这个方法实际上只是隐藏了内联内容的输出。所以,仍然可以通过向页面发送原始的POST数据来修改它们,比如使用curl
(不过“攻击者”(也就是管理员用户;-))必须了解django以及它是如何生成表单集中的字段名称的)。
现在tabular.html
可能看起来像这样:
{% 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>