chore: cleanup and add support for Python 3.9
parent
b56ded8f0f
commit
51f850f04b
10
.travis.yml
10
.travis.yml
|
|
@ -3,22 +3,18 @@ arch:
|
|||
- ppc64le
|
||||
language: python
|
||||
python:
|
||||
- "3.5"
|
||||
- "3.6"
|
||||
- "3.7"
|
||||
- "3.8"
|
||||
- "3.9"
|
||||
env:
|
||||
- DJANGO_VERSION=2.2 SAMPLE_PROJECT=sample_project
|
||||
- DJANGO_VERSION=3.0 SAMPLE_PROJECT=sample_project
|
||||
- DJANGO_VERSION=3.1 SAMPLE_PROJECT=sample_project
|
||||
- DJANGO_VERSION=3.2 SAMPLE_PROJECT=sample_project
|
||||
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
matrix:
|
||||
exclude:
|
||||
-
|
||||
python: "3.5"
|
||||
env: DJANGO_VERSION=3.0 SAMPLE_PROJECT=sample_project
|
||||
|
||||
install:
|
||||
- pip install django==$DJANGO_VERSION
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
VERSION = (2, 2, 3)
|
||||
VERSION = (2, 2, 4)
|
||||
DEV_N = None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
import json
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from django import VERSION
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url
|
||||
from django.conf.urls import re_path
|
||||
from django.contrib.admin import ModelAdmin, TabularInline, StackedInline
|
||||
from django.contrib.admin.options import InlineModelAdmin
|
||||
from django.contrib.admin.views.main import IGNORED_PARAMS, PAGE_VAR
|
||||
|
|
@ -13,7 +11,7 @@ from django.contrib.contenttypes.admin import (GenericStackedInline,
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse, HttpResponseBadRequest
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import render
|
||||
from django.template.defaultfilters import capfirst
|
||||
from django.utils.decorators import method_decorator
|
||||
|
|
@ -116,13 +114,13 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
info = self.model._meta.app_label, self.model._meta.model_name
|
||||
|
||||
# this ajax view changes the order of instances of the model type
|
||||
admin_do_sorting_url = url(
|
||||
admin_do_sorting_url = re_path(
|
||||
r'^sort/do-sorting/(?P<model_type_id>\d+)/$',
|
||||
self.admin_site.admin_view(self.do_sorting_view),
|
||||
name='%s_%s_do_sorting' % info)
|
||||
|
||||
# this view displays the sortable objects
|
||||
admin_sort_url = url(
|
||||
admin_sort_url = re_path(
|
||||
r'^sort/$',
|
||||
self.admin_site.admin_view(self.sort_view),
|
||||
name='%s_%s_sort' % info)
|
||||
|
|
@ -163,8 +161,7 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
|
||||
opts = self.model._meta
|
||||
|
||||
jquery_lib_path = 'admin/js/jquery.js' if VERSION < (1, 9) \
|
||||
else 'admin/js/vendor/jquery/jquery.js'
|
||||
jquery_lib_path = 'admin/js/vendor/jquery/jquery.js'
|
||||
|
||||
# Determine if we need to regroup objects relative to a
|
||||
# foreign key specified on the model class that is extending Sortable.
|
||||
|
|
@ -179,23 +176,13 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
|
||||
for field in self.model._meta.fields:
|
||||
if isinstance(field, SortableForeignKey):
|
||||
try:
|
||||
sortable_by_fk = field.remote_field.model
|
||||
except AttributeError:
|
||||
# Django < 1.9
|
||||
sortable_by_fk = field.rel.to
|
||||
sortable_by_field_name = field.name.lower()
|
||||
sortable_by_class_is_sortable = \
|
||||
isinstance(sortable_by_fk, SortableMixin) and \
|
||||
sortable_by_fk.objects.count() >= 2
|
||||
|
||||
if sortable_by_property:
|
||||
# backwards compatibility for < 1.1.1, where sortable_by was a
|
||||
# classmethod instead of a property
|
||||
try:
|
||||
sortable_by_class, sortable_by_expression = \
|
||||
sortable_by_property()
|
||||
except (TypeError, ValueError):
|
||||
sortable_by_class = self.model.sortable_by
|
||||
sortable_by_expression = sortable_by_class.__name__.lower()
|
||||
|
||||
|
|
@ -234,9 +221,6 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
except AttributeError:
|
||||
verbose_name_plural = opts.verbose_name_plural
|
||||
|
||||
if VERSION <= (1, 7):
|
||||
context = {}
|
||||
else:
|
||||
context = self.admin_site.each_context(request)
|
||||
|
||||
filters = urlencode(self.get_querystring_filters(request))
|
||||
|
|
@ -297,7 +281,7 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
|
||||
response = {'objects_sorted': False}
|
||||
|
||||
if request.is_ajax():
|
||||
if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
|
||||
klass = ContentType.objects.get(id=model_type_id).model_class()
|
||||
|
||||
indexes = [str(idx) for idx in request.POST.get('indexes', []).split(',')]
|
||||
|
|
@ -311,25 +295,15 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
qs = klass.objects.select_for_update().filter(**filters)
|
||||
|
||||
with transaction.atomic():
|
||||
|
||||
# Python 3.6+ only
|
||||
# objects_dict = {str(obj.pk): obj for obj in qs}
|
||||
# objects_list = list(objects_dict.keys())
|
||||
objects_dict = {}
|
||||
objects_list = []
|
||||
for obj in qs:
|
||||
key = str(obj.pk)
|
||||
objects_dict[key] = obj
|
||||
objects_list.append(key)
|
||||
objects_dict = {str(obj.pk): obj for obj in qs}
|
||||
objects_list = [*objects_dict.keys()]
|
||||
if len(indexes) != len(objects_dict):
|
||||
return HttpResponseBadRequest(
|
||||
json.dumps({
|
||||
return JsonResponse({
|
||||
'objects_sorted': False,
|
||||
'reason': _("An object has been added or removed "
|
||||
"since the last load. Please refresh "
|
||||
"the page and try reordering again."),
|
||||
}, ensure_ascii=False),
|
||||
content_type='application/json')
|
||||
}, status_code=400)
|
||||
order_field_name = klass._meta.ordering[0]
|
||||
|
||||
if order_field_name.startswith('-'):
|
||||
|
|
@ -357,8 +331,7 @@ class SortableAdmin(SortableAdminBase, ModelAdmin):
|
|||
|
||||
self.after_sorting()
|
||||
|
||||
return HttpResponse(json.dumps(response, ensure_ascii=False),
|
||||
content_type='application/json')
|
||||
return JsonResponse(response)
|
||||
|
||||
|
||||
class NonSortableParentAdmin(SortableAdmin):
|
||||
|
|
@ -387,31 +360,19 @@ class SortableInlineBase(SortableAdminBase, InlineModelAdmin):
|
|||
|
||||
class SortableTabularInline(TabularInline, SortableInlineBase):
|
||||
"""Custom template that enables sorting for tabular inlines"""
|
||||
if VERSION >= (2, 0):
|
||||
template = 'adminsortable/edit_inline/tabular-1.10.x.html'
|
||||
else:
|
||||
template = 'adminsortable/edit_inline/tabular.html'
|
||||
|
||||
|
||||
class SortableStackedInline(StackedInline, SortableInlineBase):
|
||||
"""Custom template that enables sorting for stacked inlines"""
|
||||
if VERSION >= (2, 0):
|
||||
template = 'adminsortable/edit_inline/stacked-1.10.x.html'
|
||||
else:
|
||||
template = 'adminsortable/edit_inline/stacked.html'
|
||||
|
||||
|
||||
class SortableGenericTabularInline(GenericTabularInline, SortableInlineBase):
|
||||
"""Custom template that enables sorting for tabular inlines"""
|
||||
if VERSION >= (2, 0):
|
||||
template = 'adminsortable/edit_inline/tabular-1.10.x.html'
|
||||
else:
|
||||
template = 'adminsortable/edit_inline/tabular.html'
|
||||
|
||||
|
||||
class SortableGenericStackedInline(GenericStackedInline, SortableInlineBase):
|
||||
"""Custom template that enables sorting for stacked inlines"""
|
||||
if VERSION >= (2, 0):
|
||||
template = 'adminsortable/edit_inline/stacked-1.10.x.html'
|
||||
else:
|
||||
template = 'adminsortable/edit_inline/stacked.html'
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
{% load i18n admin_urls static %}
|
||||
<div class="js-inline-admin-formset inline-group"
|
||||
id="{{ inline_admin_formset.formset.prefix }}-group"
|
||||
data-inline-type="stacked"
|
||||
data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
|
||||
<fieldset class="module {{ inline_admin_formset.classes }}">
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
|
||||
{{ inline_admin_formset.formset.management_form }}
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
|
||||
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if inline_admin_form.original or inline_admin_form.show_url %} 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>
|
||||
{% if inline_admin_form.original %}
|
||||
{% with initial_forms_count=inline_admin_formset.formset.management_form.INITIAL_FORMS.value %}
|
||||
<i class="fa fa-{% if forloop.first %}sort-desc{% elif forloop.counter == initial_forms_count %}sort-asc{% else %}sort{% endif %}"></i>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
<b>{{ inline_admin_formset.opts.verbose_name|capfirst }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} <a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="inlinechangelink">{% trans "Change" %}</a>{% endif %}
|
||||
{% else %}#{{ forloop.counter }}{% endif %}</span>
|
||||
{% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% 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 %}
|
||||
</h3>
|
||||
{% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
|
||||
{% for fieldset in inline_admin_form %}
|
||||
{% include "admin/includes/fieldset.html" %}
|
||||
{% endfor %}
|
||||
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{{ inline_admin_form.fk_field.field }}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url opts|admin_urlname:'do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
</div>{% endfor %}
|
||||
</fieldset>
|
||||
</div>
|
||||
|
|
@ -1,41 +1,34 @@
|
|||
{% load i18n admin_urls static django_template_additions %}
|
||||
{% get_django_version as django_version %}
|
||||
<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>
|
||||
{% load i18n admin_urls static %}
|
||||
<div class="js-inline-admin-formset inline-group"
|
||||
id="{{ inline_admin_formset.formset.prefix }}-group"
|
||||
data-inline-type="stacked"
|
||||
data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
|
||||
<fieldset class="module {{ inline_admin_formset.classes }}">
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
|
||||
{{ inline_admin_formset.formset.management_form }}
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
|
||||
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related {% if django_version.major >= 1 and django_version.minor >= 9 %}flat-admin{% endif %} {% if forloop.last %} empty-form last-related{% endif %} {% if inline_admin_form.original %} has_original{% 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 or inline_admin_form.show_url %} 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>
|
||||
{% if inline_admin_form.original %}
|
||||
{% with initial_forms_count=inline_admin_formset.formset.management_form.INITIAL_FORMS.value %}
|
||||
<i class="fa fa-{% if forloop.first %}sort-desc{% elif forloop.counter == initial_forms_count %}sort-asc{% else %}sort{% endif %}"></i>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
<b>{{ inline_admin_formset.opts.verbose_name|title }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} <a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="inlinechangelink">{% trans "Change" %}</a>{% endif %}
|
||||
{% 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 %}
|
||||
<b>{{ inline_admin_formset.opts.verbose_name|capfirst }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %} <a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="inlinechangelink">{% trans "Change" %}</a>{% endif %}
|
||||
{% else %}#{{ forloop.counter }}{% endif %}</span>
|
||||
{% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% 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 %}
|
||||
</h3>
|
||||
{% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
|
||||
{% for fieldset in inline_admin_form %}
|
||||
{% include "admin/includes/fieldset.html" %}
|
||||
{% endfor %}
|
||||
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{{ inline_admin_form.fk_field.field }}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url opts|admin_urlname:'do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{{ inline_admin_form.fk_field.field }}
|
||||
</div>{% endfor %}
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function($) {
|
||||
$("#{{ inline_admin_formset.formset.prefix }}-group .inline-related").stackedFormset({
|
||||
prefix: '{{ inline_admin_formset.formset.prefix }}',
|
||||
adminStaticPrefix: '{% static "admin/" %}',
|
||||
deleteText: "{% trans "Remove" %}",
|
||||
addText: "{% blocktrans with verbose_name=inline_admin_formset.opts.verbose_name|title %}Add another {{ verbose_name }}{% endblocktrans %}"
|
||||
});
|
||||
})(django.jQuery);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
{% load i18n admin_urls static admin_modify django_template_additions %}
|
||||
<div class="js-inline-admin-formset inline-group" id="{{ inline_admin_formset.formset.prefix }}-group"
|
||||
data-inline-type="tabular"
|
||||
data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
|
||||
<div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
|
||||
{{ inline_admin_formset.formset.management_form }}
|
||||
<fieldset class="module {{ inline_admin_formset.classes }}">
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th class="original"></th>
|
||||
{% for field in inline_admin_formset.fields %}
|
||||
{% if not field.widget.is_hidden %}
|
||||
<th{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}
|
||||
{% if field.help_text %} <img src="{% static "admin/img/icon-unknown.svg" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}" />{% endif %}
|
||||
</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 inline_admin_form.form.non_field_errors %}
|
||||
<tr><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
|
||||
{% 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 %}"
|
||||
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>
|
||||
{% with initial_forms_count=inline_admin_form.formset.management_form.INITIAL_FORMS.value %}
|
||||
<i class="fa fa-{% if forloop.first %}sort-desc{% elif forloop.counter == initial_forms_count %}sort-asc{% else %}sort{% endif %}"></i>
|
||||
{% endwith %}
|
||||
{% if inline_admin_form.original %}
|
||||
{{ inline_admin_form.original }}
|
||||
{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %}<a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="inlinechangelink">{% trans "Change" %}</a>{% endif %}
|
||||
{% endif %}
|
||||
{% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% trans "View on site" %}</a>{% endif %}
|
||||
</p>{% endif %}
|
||||
{% if inline_admin_form.needs_explicit_pk_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.field.is_hidden %} {{ field.field }} {% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endspaceless %}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url opts|admin_urlname:'do_sorting' inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
</td>
|
||||
{% for fieldset in inline_admin_form %}
|
||||
{% for line in fieldset %}
|
||||
{% for field in line %}
|
||||
{% if not field.field.is_hidden %}
|
||||
<td{% if field.field.name %} class="field-{{ field.field.name }}"{% endif %}>
|
||||
{% if field.is_readonly %}
|
||||
<p>{{ field.contents }}</p>
|
||||
{% else %}
|
||||
{{ field.field.errors.as_ul }}
|
||||
{{ field.field }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% 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>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
{% load i18n admin_urls static admin_modify django_template_additions %}{% load cycle from future %}
|
||||
{% get_django_version as django_version %}
|
||||
<div class="inline-group {% if django_version.major >= 1 and django_version.minor >= 9 %}flat-admin{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-group">
|
||||
{% load i18n admin_urls static admin_modify django_template_additions %}
|
||||
<div class="js-inline-admin-formset inline-group" id="{{ inline_admin_formset.formset.prefix }}-group"
|
||||
data-inline-type="tabular"
|
||||
data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
|
||||
<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 }} {% if inline_admin_formset.formset.initial_form_count > 1 %} - {% trans "drag and drop to change order" %}{% endif %}</h2>
|
||||
<fieldset class="module {{ inline_admin_formset.classes }}">
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th class="original"></th>
|
||||
{% for field in inline_admin_formset.fields %}
|
||||
{% if not field.widget.is_hidden %}
|
||||
<th{% if forloop.first %} colspan="2"{% endif %}{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}
|
||||
{% if field.help_text %} <img src="{% if django_version.major >= 1 and django_version.minor >= 9 %}{% static "admin/img/icon-unknown.svg" %}{% else %}{% static "admin/img/icon-unknown.gif" %}{% endif %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}" />{% endif %}
|
||||
<th{% if field.required %} class="required"{% endif %}>{{ field.label|capfirst }}
|
||||
{% if field.help_text %} <img src="{% static "admin/img/icon-unknown.svg" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}" />{% endif %}
|
||||
</th>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
|
@ -34,7 +36,7 @@
|
|||
{{ inline_admin_form.original }}
|
||||
{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %}<a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="inlinechangelink">{% trans "Change" %}</a>{% endif %}
|
||||
{% 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 %}
|
||||
{% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% trans "View on site" %}</a>{% endif %}
|
||||
</p>{% endif %}
|
||||
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{{ inline_admin_form.fk_field.field }}
|
||||
|
|
@ -42,7 +44,7 @@
|
|||
{% for fieldset in inline_admin_form %}
|
||||
{% for line in fieldset %}
|
||||
{% for field in line %}
|
||||
{% if field.is_hidden %} {{ field.field }} {% endif %}
|
||||
{% if field.field.is_hidden %} {{ field.field }} {% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
|
@ -54,14 +56,16 @@
|
|||
{% for fieldset in inline_admin_form %}
|
||||
{% for line in fieldset %}
|
||||
{% for field in line %}
|
||||
{% if not field.field.is_hidden %}
|
||||
<td{% if field.field.name %} class="field-{{ field.field.name }}"{% endif %}>
|
||||
{% if field.is_readonly %}
|
||||
<p>{{ field.contents|linebreaksbr }}</p>
|
||||
<p>{{ field.contents }}</p>
|
||||
{% else %}
|
||||
{{ field.field.errors.as_ul }}
|
||||
{{ field.field }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
|
@ -75,15 +79,3 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
(function($) {
|
||||
$("#{{ inline_admin_formset.formset.prefix }}-group .tabular.inline-related tbody tr").tabularFormset({
|
||||
prefix: "{{ inline_admin_formset.formset.prefix }}",
|
||||
adminStaticPrefix: '{% static "admin/" %}',
|
||||
addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
|
||||
deleteText: "{% trans 'Remove' %}"
|
||||
});
|
||||
})(django.jQuery);
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -188,3 +188,5 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
]
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
||||
1
setup.py
1
setup.py
|
|
@ -12,7 +12,6 @@ setup(
|
|||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Topic :: Utilities'],
|
||||
description='Drag and drop sorting for models and inline models in Django admin.',
|
||||
|
|
|
|||
5
tox.ini
5
tox.ini
|
|
@ -1,11 +1,12 @@
|
|||
[tox]
|
||||
envlist = django{2.2,3.0}-{py36,py37,py38},coverage
|
||||
envlist = django{2.2,3.1,3.2}-{py36,py37,py38,py39},coverage
|
||||
|
||||
[testenv]
|
||||
deps =
|
||||
coverage
|
||||
django2.2: Django>=2.2
|
||||
django3.0: Django>=3.0
|
||||
django3.1: Django>=3.1
|
||||
django3.2: Django>=3.2
|
||||
whitelist_externals = cd
|
||||
setenv =
|
||||
PYTHONPATH = {toxinidir}/sample_project
|
||||
|
|
|
|||
Loading…
Reference in New Issue