chore: cleanup and add support for Python 3.9

master
Kamil Gałuszka 2021-07-17 01:05:59 +02:00
parent b56ded8f0f
commit 51f850f04b
10 changed files with 58 additions and 229 deletions

View File

@ -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

View File

@ -1,4 +1,4 @@
VERSION = (2, 2, 3)
VERSION = (2, 2, 4)
DEV_N = None

View File

@ -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,25 +176,15 @@ 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_fk = field.remote_field.model
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()
sortable_by_class = self.model.sortable_by
sortable_by_expression = sortable_by_class.__name__.lower()
sortable_by_class_display_name = sortable_by_class._meta \
.verbose_name_plural
@ -234,10 +221,7 @@ 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)
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'
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'
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'
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'
template = 'adminsortable/edit_inline/stacked.html'

View File

@ -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>&nbsp;<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>

View File

@ -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>&nbsp;<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>&nbsp;<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>

View File

@ -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 %}&nbsp;<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>

View File

@ -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 %}&nbsp;<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 %}&nbsp;<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 %}
@ -31,10 +33,10 @@
<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 %}
{{ 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>

View File

@ -188,3 +188,5 @@ AUTH_PASSWORD_VALIDATORS = [
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

View File

@ -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.',

View File

@ -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