Added new stacked and tabular change form templates for inlines from Django 1.6.

Added backwards compatibility changes for the setting of the edit inline template to use.
master
Brandon Taylor 2013-11-25 22:03:20 -05:00
parent 03a3a0a51d
commit 469e7d5d4d
6 changed files with 135 additions and 227 deletions

View File

@ -1,6 +1,6 @@
# Django Admin Sortable # Django Admin Sortable
Current version: 1.6.1 Current version: 1.6.2
This project makes it easy to add drag-and-drop ordering to any model in This project makes it easy to add drag-and-drop ordering to any model in
Django admin. Inlines for a sortable model may also be made sortable, Django admin. Inlines for a sortable model may also be made sortable,
@ -284,10 +284,10 @@ ordering on top of that just seemed a little much in my opinion.
django-admin-sortable is currently used in production. django-admin-sortable is currently used in production.
### What's new in 1.6.1? ### What's new in 1.6.2?
- Faster query counting - thanks [PyKaB](https://github.com/PyKaB) - Faster query counting - thanks [PyKaB](https://github.com/PyKaB)
- Updated jQueryUI to be compatible with jQuery 1.9.x or higher. - Updated jQueryUI to be compatible with jQuery 1.9.x or higher.
- Django 1.6 compatibility - Django 1.6 compatibility, with [fixes for inline models](https://github.com/iambrandontaylor/django-admin-sortable/issues/64).
- Fixed the link to jQueryUI in the admin sortable change form (facepalm) - Fixed the link to jQueryUI in the admin sortable change form (facepalm)

View File

@ -1,4 +1,4 @@
VERSION = (1, 6, 1) # following PEP 386 VERSION = (1, 6, 2) # following PEP 386
DEV_N = None DEV_N = None

View File

@ -268,19 +268,31 @@ class SortableInlineBase(SortableAdminBase, InlineModelAdmin):
class SortableTabularInline(TabularInline, SortableInlineBase): class SortableTabularInline(TabularInline, SortableInlineBase):
"""Custom template that enables sorting for tabular inlines""" """Custom template that enables sorting for tabular inlines"""
template = 'adminsortable/edit_inline/tabular.html' if DJANGO_MINOR_VERSION <= 5:
template = 'adminsortable/edit_inline/tabular-1.5.x.html'
else:
template = 'adminsortable/edit_inline/tabular.html'
class SortableStackedInline(StackedInline, SortableInlineBase): class SortableStackedInline(StackedInline, SortableInlineBase):
"""Custom template that enables sorting for stacked inlines""" """Custom template that enables sorting for stacked inlines"""
template = 'adminsortable/edit_inline/stacked.html' if DJANGO_MINOR_VERSION <= 5:
template = 'adminsortable/edit_inline/stacked-1.5.x.html'
else:
template = 'adminsortable/edit_inline/stacked.html'
class SortableGenericTabularInline(GenericTabularInline, SortableInlineBase): class SortableGenericTabularInline(GenericTabularInline, SortableInlineBase):
"""Custom template that enables sorting for tabular inlines""" """Custom template that enables sorting for tabular inlines"""
template = 'adminsortable/edit_inline/tabular.html' if DJANGO_MINOR_VERSION <= 5:
template = 'adminsortable/edit_inline/tabular-1.5.x.html'
else:
template = 'adminsortable/edit_inline/tabular.html'
class SortableGenericStackedInline(GenericStackedInline, SortableInlineBase): class SortableGenericStackedInline(GenericStackedInline, SortableInlineBase):
"""Custom template that enables sorting for stacked inlines""" """Custom template that enables sorting for stacked inlines"""
template = 'adminsortable/edit_inline/stacked.html' if DJANGO_MINOR_VERSION <= 5:
template = 'adminsortable/edit_inline/stacked-1.5.x.html'
else:
template = 'adminsortable/edit_inline/stacked.html'

View File

@ -1,86 +1,33 @@
{% load i18n admin_modify adminsortable_tags %} {% load i18n admin_static %}
{% load static from staticfiles %} <div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group"> <h2>{{ inline_admin_formset.opts.verbose_name_plural|title }} {% if inline_admin_formset.formset.initial_form_count > 1 %} - {% trans "drag and drop to change order" %}{% endif %}</h2>
<h2>{{ inline_admin_formset.opts.verbose_name_plural|title }} {% if inline_admin_formset.formset.initial_form_count > 1 %} - {% trans "drag and drop to change order" %}{% endif %}</h2> {{ inline_admin_formset.formset.management_form }}
{{ inline_admin_formset.formset.management_form }} {{ inline_admin_formset.formset.non_form_errors }}
{{ inline_admin_formset.formset.non_form_errors }}
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if forloop.last %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if inline_admin_form.original %} has_original{% endif %}{% if forloop.last %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}"> <h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b>&nbsp;<span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span>
<h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b>&nbsp;<span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span> {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% 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 %} {% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
{% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %} </h3>
</h3> {% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
{% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %} {% for fieldset in inline_admin_form %}
{% for fieldset in inline_admin_form %} {% include "admin/includes/fieldset.html" %}
{% include "admin/includes/fieldset.html" %} {% endfor %}
{% endfor %} {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %} {{ inline_admin_form.fk_field.field }}
{{ inline_admin_form.fk_field.field }} {% if inline_admin_form.original %}
{% if inline_admin_form.original %} <input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" />
<input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" /> {% endif %}
{% endif %} </div>{% endfor %}
</div>{% endfor %} </div>
</div>
<script type="text/javascript">
<script type="text/javascript"> (function($) {
(function($) { $("#{{ inline_admin_formset.formset.prefix }}-group .inline-related").stackedFormset({
$(document).ready(function() { prefix: '{{ inline_admin_formset.formset.prefix }}',
var rows = "#{{ inline_admin_formset.formset.prefix }}-group .inline-related"; adminStaticPrefix: '{% static "admin/" %}',
var updateInlineLabel = function(row) { deleteText: "{% trans "Remove" %}",
$(rows).find(".inline_label").each(function(i) { addText: "{% blocktrans with verbose_name=inline_admin_formset.opts.verbose_name|title %}Add another {{ verbose_name }}{% endblocktrans %}"
var count = i + 1; });
$(this).html($(this).html().replace(/(#\d+)/g, "#" + count)); })(django.jQuery);
}); </script>
}
var reinitDateTimeShortCuts = function() {
// Reinitialize the calendar and clock widgets by force, yuck.
if (typeof DateTimeShortcuts != "undefined") {
$(".datetimeshortcuts").remove();
DateTimeShortcuts.init();
}
}
var updateSelectFilter = function() {
// If any SelectFilter widgets were added, instantiate a new instance.
if (typeof SelectFilter != "undefined"){
$(".selectfilter").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], false, "{% static 'admin/' %}");
});
$(".selectfilterstacked").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], true, "{% static 'admin/' %}");
});
}
}
var initPrepopulatedFields = function(row) {
row.find('.prepopulated_field').each(function() {
var field = $(this);
var input = field.find('input, select, textarea');
var dependency_list = input.data('dependency_list') || [];
var dependencies = [];
$.each(dependency_list, function(i, field_name) {
dependencies.push('#' + row.find(field_name).find('input, select, textarea').attr('id'));
});
if (dependencies.length) {
input.prepopulate(dependencies, input.attr('maxlength'));
}
});
}
$(rows).formset({
prefix: "{{ inline_admin_formset.formset.prefix }}",
addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
formCssClass: "dynamic-{{ inline_admin_formset.formset.prefix }}",
deleteCssClass: "inline-deletelink",
deleteText: "{% trans "Remove" %}",
emptyCssClass: "empty-form",
removed: updateInlineLabel,
added: (function(row) {
initPrepopulatedFields(row);
reinitDateTimeShortCuts();
updateSelectFilter();
updateInlineLabel(row);
})
});
});
})(django.jQuery);
</script>

View File

@ -1,133 +1,82 @@
{% load i18n admin_modify adminsortable_tags %} {% load i18n admin_static admin_modify %}{% load cycle from future %}
{% load static from staticfiles %} <div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group"> <div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
<div class="tabular inline-related {% if forloop.last %}last-related{% endif %}"> {{ inline_admin_formset.formset.management_form }}
{{ inline_admin_formset.formset.management_form }} <fieldset class="module">
<fieldset class="module"> <h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }} {% if inline_admin_formset.formset.initial_form_count > 1 %} - {% trans "drag and drop to change order" %}{% endif %}</h2>
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }} {% if inline_admin_formset.formset.initial_form_count > 1 %} - {% trans "drag and drop to change order" %}{% endif %}</h2> {{ inline_admin_formset.formset.non_form_errors }}
{{ inline_admin_formset.formset.non_form_errors }} <table>
<table> <thead><tr>
<thead><tr> {% for field in inline_admin_formset.fields %}
{% for field in inline_admin_formset.fields %} {% if not field.widget.is_hidden %}
{% if not field.widget.is_hidden %} <th{% if forloop.first %} colspan="2"{% endif %}{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}
<th{% if forloop.first %} colspan="2"{% endif %}{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}</th> {% if field.help_text %}&nbsp;<img src="{% static "admin/img/icon-unknown.gif" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}" />{% endif %}
{% endif %} </th>
{% endfor %} {% endif %}
{% if inline_admin_formset.formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %} {% endfor %}
</tr></thead> {% if inline_admin_formset.formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %}
</tr></thead>
<tbody>
{% for inline_admin_form in inline_admin_formset %} <tbody>
{% if inline_admin_form.form.non_field_errors %} {% for inline_admin_form in inline_admin_formset %}
<tr><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr> {% if inline_admin_form.form.non_field_errors %}
{% endif %} <tr><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
<tr class="{% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last %} empty-form{% endif %}" {% endif %}
id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}"> <tr class="form-row {% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last %} empty-form{% endif %}"
<td class="original"> id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
<td class="original">
{% if inline_admin_form.original or inline_admin_form.show_url %}<p> {% 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.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 %} {% if inline_admin_form.show_url %}<a href="{% url 'admin:view_on_site' inline_admin_form.original_content_type_id inline_admin_form.original.pk %}">{% trans "View on site" %}</a>{% endif %}
</p>{% endif %} </p>{% endif %}
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %} {% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
{{ inline_admin_form.fk_field.field }} {{ inline_admin_form.fk_field.field }}
{% spaceless %} {% spaceless %}
{% for fieldset in inline_admin_form %} {% for fieldset in inline_admin_form %}
{% for line in fieldset %} {% for line in fieldset %}
{% for field in line %} {% for field in line %}
{% if field.is_hidden %} {{ field.field }} {% endif %} {% if field.is_hidden %} {{ field.field }} {% endif %}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% endspaceless %} {% endspaceless %}
{% if inline_admin_form.original %} {% if inline_admin_form.original %}
<input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" /> <input type="hidden" name="admin_sorting_url" value="{% url 'admin:admin_do_sorting' inline_admin_form.original.model_type_id %}" />
{% endif %} {% endif %}
</td> </td>
{% for fieldset in inline_admin_form %} {% for fieldset in inline_admin_form %}
{% for line in fieldset %} {% for line in fieldset %}
{% for field in line %} {% for field in line %}
<td class="{{ field.field.name }}"> <td{% if field.field.name %} class="field-{{ field.field.name }}"{% endif %}>
{% if field.is_readonly %} {% if field.is_readonly %}
<p>{{ field.contents }}</p> <p>{{ field.contents|linebreaksbr }}</p>
{% else %} {% else %}
{{ field.field.errors.as_ul }} {{ field.field.errors.as_ul }}
{{ field.field }} {{ field.field }}
{% endif %} {% endif %}
</td> </td>
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% if inline_admin_formset.formset.can_delete %} {% if inline_admin_formset.formset.can_delete %}
<td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td> <td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td>
{% endif %} {% endif %}
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</fieldset> </fieldset>
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
(function($) {
$(document).ready(function($) { (function($) {
var rows = "#{{ inline_admin_formset.formset.prefix }}-group .tabular.inline-related tbody tr"; $("#{{ inline_admin_formset.formset.prefix }}-group .tabular.inline-related tbody tr").tabularFormset({
var alternatingRows = function(row) { prefix: "{{ inline_admin_formset.formset.prefix }}",
$(rows).not(".add-row").removeClass("row1 row2") adminStaticPrefix: '{% static "admin/" %}',
.filter(":even").addClass("row1").end() addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
.filter(rows + ":odd").addClass("row2"); deleteText: "{% trans 'Remove' %}"
} });
var reinitDateTimeShortCuts = function() { })(django.jQuery);
// Reinitialize the calendar and clock widgets by force </script>
if (typeof DateTimeShortcuts != "undefined") {
$(".datetimeshortcuts").remove();
DateTimeShortcuts.init();
}
}
var updateSelectFilter = function() {
// If any SelectFilter widgets are a part of the new form,
// instantiate a new SelectFilter instance for it.
if (typeof SelectFilter != "undefined"){
$(".selectfilter").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], false, "{% static 'admin/' %}");
});
$(".selectfilterstacked").each(function(index, value){
var namearr = value.name.split('-');
SelectFilter.init(value.id, namearr[namearr.length-1], true, "{% static 'admin/' %}");
});
}
}
var initPrepopulatedFields = function(row) {
row.find('.prepopulated_field').each(function() {
var field = $(this);
var input = field.find('input, select, textarea');
var dependency_list = input.data('dependency_list') || [];
var dependencies = [];
$.each(dependency_list, function(i, field_name) {
dependencies.push('#' + row.find(field_name).find('input, select, textarea').attr('id'));
});
if (dependencies.length) {
input.prepopulate(dependencies, input.attr('maxlength'));
}
});
}
$(rows).formset({
prefix: "{{ inline_admin_formset.formset.prefix }}",
addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
formCssClass: "dynamic-{{ inline_admin_formset.formset.prefix }}",
deleteCssClass: "inline-deletelink",
deleteText: "{% trans "Remove" %}",
emptyCssClass: "empty-form",
removed: alternatingRows,
added: (function(row) {
initPrepopulatedFields(row);
reinitDateTimeShortCuts();
updateSelectFilter();
alternatingRows(row);
})
});
});
})(django.jQuery);
</script>